C++ GUI Programming with Qt4 笔记 -- chap2 QDialog
以 finddialog 为例,介绍 QDialog。并对 Qt 的基本概念和技巧做了更进一步(chap1)的介绍。
1.MOC 扩展与signals–slots 机制
严格来说,Qt 开发,写的并不是标准 C++。
Meta-Object System 是 Qt 对 C++ 的一项重要扩展,简称 moc。
moc is a mechanism for creating independent software components
that can be bound together without any component knowing anything about the other components it is connected to
提供了 2 个关键内容:signals–slots and introspection。
其中,introspection 是实现 signals–slots 的基础。
The mechanism works as follows:
The Q_OBJECT macro declares some introspection functions that must be implemented in every QObject subclass: metaObject(), tr(), qt_metacall(), and a few more.
Qt's moc tool generates implementations for the functions declared by Q_OBJECT and for all the signals.
QObject member functions such as connect() and disconnect() use the introspection functions to do their work.
All of this is handled automatically by qmake, moc, and QObject, so you rarely need to think about it.
But if you are curious, you can read the QMetaObject class documentation
and have a look at the C++ source files generated by moc to see how the implementation works.
2. 技巧与细节
2.1 class forward declaration
在头文件中,如果只用到了某个类的指针,不依赖于类的定义与实现。
可以使用 class ClassName 声明类,取代 #include "ClassName.h"
相比于加载头文件,前置声明更简洁,性能更好。
2.2 国际化:用户可见的文字,使用 tr()
2.3 快捷键:使用 & 声明快捷键。
例如 &Find 声明快捷键为 F,
setBuddy(widget) 设置快捷键按下时,focus 到 widget 组件上,而非自身。
2.4 setDefault 按下 Enter 键时的行为。
2.5 setLayout 时会重新计算父子关系。
layout 中的所有组件,都变成 setLayout 对象的子对象。
2.6 使用 moc 机制(Q_OBJECT)时,类的定义必须在 .h 文件中,否则 moc 不会正常工作。
// finddialog.h
#ifndef FINDDIALOG_H
#define FINDDIALOG_H #include <QDialog> class QCheckBox;
class QLabel;
class QLineEdit;
class QPushButton; class FindDialog : public QDialog
{
Q_OBJECT
public:
FindDialog(QWidget *parent = );
signals:
void findNext(const QString &str, Qt::CaseSensitivity cs);
void findPrevious(const QString &str, Qt::CaseSensitivity cs);
private slots:
void findClicked();
void enableFindButton(const QString &text);
private:
QLabel *label;
QLineEdit *lineEdit;
QCheckBox *caseCheckBox;
QCheckBox *backwardCheckBox;
QPushButton *findButton;
QPushButton *closeButton;
}; #endif
// finddialog.cpp
#include <QtGui>
#include "finddialog.h" FindDialog::FindDialog(QWidget *parent)
: QDialog(parent)
{
// widgets
label = new QLabel(tr("Find &what: "));
lineEdit = new QLineEdit;
label->setBuddy(lineEdit); caseCheckBox = new QCheckBox(tr("Match &case"));
backwardCheckBox = new QCheckBox(tr("Search &backward")); findButton = new QPushButton(tr("&Find"));
findButton->setDefault(true);
findButton->setEnabled(false);
closeButton = new QPushButton(tr("Close")); // connections
connect(lineEdit, SIGNAL(textChanged(const QString &)),
this, SLOT(enableFindButton(const QString &)));
connect(findButton, SIGNAL(clicked()),
this, SLOT(findClicked()));
connect(closeButton, SIGNAL(clicked()),
this, SLOT(close())); // layout
QHBoxLayout *topLeftLayout = new QHBoxLayout;
topLeftLayout->addWidget(label);
topLeftLayout->addWidget(lineEdit); QVBoxLayout *leftLayout = new QVBoxLayout;
leftLayout->addLayout(topLeftLayout);
leftLayout->addWidget(caseCheckBox);
leftLayout->addWidget(backwardCheckBox); QVBoxLayout *rightLayout = new QVBoxLayout;
rightLayout->addWidget(findButton);
rightLayout->addWidget(closeButton);
rightLayout->addStretch(); QHBoxLayout *mainLayout = new QHBoxLayout;
mainLayout->addLayout(leftLayout);
mainLayout->addLayout(rightLayout); setLayout(mainLayout);
setWindowTitle(tr("Find"));
setFixedHeight(sizeHint().height());
} void FindDialog::findClicked()
{
QString text = lineEdit->text();
Qt::CaseSensitivity cs =
caseCheckBox->isChecked() ? Qt::CaseSensitive
: Qt::CaseInsensitive;
if (backwardCheckBox->isChecked()) {
emit findPrevious(text, cs);
} else {
emit findNext(text, cs);
}
} void FindDialog::enableFindButton(const QString &text)
{
findButton->setEnabled(!text.isEmpty());
}
// main.cpp
#include <QApplication>
#include "finddialog.h" int main(int argc, char *argv[])
{
QApplication app(argc, argv);
FindDialog *dialog = new FindDialog;
dialog->show();
return app.exec();
}
C++ GUI Programming with Qt4 笔记 -- chap2 QDialog的更多相关文章
- C++ GUI Programming with Qt4 笔记 -- chap1
1. Hello Qt #include <QApplication> #include <QLabel> int main(int argc, char *argv[]){ ...
- 2018-12-09 疑似bug_中文代码示例之Programming in Scala笔记第九十章
续前文: 中文代码示例之Programming in Scala笔记第七八章 源文档库: program-in-chinese/Programming_in_Scala_study_notes_zh ...
- 2018-11-27 中文代码示例之Programming in Scala笔记第七八章
续前文: 中文代码示例之Programming in Scala学习笔记第二三章 中文代码示例之Programming in Scala笔记第四五六章. 同样仅节选有意思的例程部分作演示之用. 源文档 ...
- 2018-11-16 中文代码示例之Programming in Scala笔记第四五六章
续前文: 中文代码示例之Programming in Scala学习笔记第二三章. 同样仅节选有意思的例程部分作演示之用. 源文档仍在: program-in-chinese/Programming_ ...
- Dynamic Programming 动态规划入门笔记
算法导论笔记 programming 指的是一种表格法,并非编写计算机程序 动态规划与分治方法相似,都是通过组合子问题的解来求解原问题.但是分治法将问题划分为互不相交的子问题.而动态规划是应用与子问题 ...
- C++ Programming language读书笔记
C语言,结构化程序设计.自顶向下.逐步求精及模块化的程序设计方法;使用三种基本控制结构构造程序,任何程序都可由顺序.选择.循环三种基本控制结构构造. 模块结构:"独立功能,单出.入口&quo ...
- OpenCV 2 Computer Vision Application Programming Cookbook读书笔记
### `highgui`的常用函数: `cv::namedWindow`:一个命名窗口 `cv::imshow`:在指定窗口显示图像 `cv::waitKey`:等待按键 ### 像素级 * 在灰度 ...
- 九章算法系列(#4 Dynamic Programming)-课堂笔记
前言 时隔这么久才发了这篇早在三周前就应该发出来的课堂笔记,由于懒癌犯了,加上各种原因,实在是应该反思.好多课堂上老师说的重要的东西可能细节上有一些急记不住了,但是幸好做了一些笔记,还能够让自己回想起 ...
- the C programming language 阅读笔记1
读了一遍著名的<the C programming language>,果然如听说的一样,讲解基础透彻,案例简单典型,确实自己C语言还有很多细节点不是很清楚. 总结一下阅读的收获(部分原书 ...
随机推荐
- [C语言(VC)] 打造自己的键盘记录器 (zaroty)
说起键盘记录,想必很多朋友都用过网上流传的一些键盘记录软件吧,但是有没有想过自己写一个呢?也许你会想:会不会很复杂啊?我可以很负责的告诉你,写键盘记录是很简单的.你所需要的仅仅是懂得一些C语言的DLL ...
- iOS开发——数据持久化Swift篇&通用文件存储
通用文件存储 import UIKit class ViewController: UIViewController { @IBOutlet weak var textField: UITextFie ...
- (inline)内联函数在IOS开发中的使用
今天在阅读YYKit源码(https://github.com/ibireme/YYKit.git)时发现在YYKitMacro.h组件中大量使用的内联函数,例如此文件中的一个函数 static in ...
- Android_ViewFlipper
xml: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:t ...
- RecyclerView, ListView 只显示一行内容 问题解决
Adapter 中的data有多行,但是RecyclerView只显示一行. 原因出在item的layout xml, 用了自动生成的RelativeLayout, 她的默认高度height属性是ma ...
- 关于Git的工作区域和对应的文件状态.
Git是一个免费的.分布式的版本控制工具,或是一个强调了速度快的源代码管理工具.每一个Git的工作目录都是一个完全独立的代码库,并拥有完整的历史记录和版本追踪能力,不依赖于网络和中心服务器. Git ...
- akka创建actor时报错:IllegalArgumentException: no matching constructor found on class $iwC$$iwC$$iwC$$iwC$
在spark-shell中输入范例中的代码: import akka.actor.Actor import akka.actor.Props import akka.event.Logging cla ...
- 快速了解Scala技术栈
http://www.infoq.com/cn/articles/scala-technology/ 我无可救药地成为了Scala的超级粉丝.在我使用Scala开发项目以及编写框架后,它就仿佛凝聚成为 ...
- WCF图片上传
WCF越来越流行,俺也在用,这是废话.项目中遇到需要图片上传,但是wcf上传会遇到一些异常,调试了N久,找了好多个解决方案才最终解决.代码直接贴上了 /// <summary> /// 笔 ...
- 在Ubuntu Linux下安装Code::Blocks和Eclipse CDT
最近小白由于有工作学习的需要,要尝试在Linux下进行C++编程.所以特地花了一点时间研究一下Linux下的C++的IDE.最后我尝试了使用Code::Blocks和Eclipse两个著 ...