(1) 部分知识点
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
//mainwidget.h #include <QWidget> //前置声明 class QLineEdit; class QPushButton; class MainWidget : public QWidget { //Q_OBJECT宏 Q_OBJECT public: explicit MainWidget(QWidget *parent = 0); //信号 signals: void outputString(const QString &str); //私有槽 private slots: void on_pushButton_clicked(); private: QLineEdit *lineEdit; QPushButton *pushButton; }; |
1)私有变量都是指针,编译程序无须这些类的完整定义,使用前置声明使得编译过程更快;
2)对于所有定义了信号和槽的类,在类定义开始处的Q_OBJECT宏都是必需的;
3)signals关键字实际上是一个宏,信号没有private/protected/public之分,信号函数不需要定义,Qt会自动实现它;
4)slots关键字也是一个宏,槽有private/protected/public之分,槽函数必须定义;
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
|
//mainwidget.cpp #include "mainwidget.h" #include <QtGui> MainWidget::MainWidget(QWidget *parent) : QWidget(parent) { //定义窗口部件,这里没有必要指定父对象 QLabel *label = new QLabel(tr("&Input:")); lineEdit = new QLineEdit; pushButton = new QPushButton(tr("&OK")); //设置部件属性 label->setBuddy(lineEdit); pushButton->setDefault(true); //添加到布局中 QHBoxLayout *layout = new QHBoxLayout; layout->addWidget(label); layout->addWidget(lineEdit); layout->addStretch(); layout->addWidget(pushButton); //为其中的部件“重定义父对象” setLayout(layout); //信号连接,SIGNAL和SLOT宏 connect(pushButton, SIGNAL(clicked()), this, SLOT(on_pushButton_clicked())); } //槽的实现 void MainWidget::on_pushButton_clicked() { //emit关键字 emit outputString(lineEdit->text()); } |
5)Qt程序员最常用的方式:定义窗口部件-->设置部件属性-->将这些窗口部件添加到布局中-->设置信号连接;
6)在定义窗口部件时有时可以不需要指定父对象,因为setLayout函数在底层实现时会自动为那些子对象“重定义父对象”;当将子布局对象添加到父布局对象中(addLayout),子布局对象会重定义自己的父对象;
7)Qt会在删除父对象时自动删除其所属的所有子对象;需要明确删除的对象是那些使用new创建的并且没有父对象的对象;如果在删除一个父对象之前删除子对象,Qt会自动地从它的父对象的子对象列表中将其移除;
8)在字符串周围的tr()函数调用是把它们编译成其他语言的标记;
9)第9和11行字符串中的“&”用来设置快捷键,14行的设置label的伙伴为lineEdit,所谓“伙伴”,就是在按下快捷键是对应窗口的伙伴部件接收角点;
10)emit是Qt的关键字,实际上也是一个宏,表示发送信号;
01 02 03 04 05 06 07 08 09 10 11 12 13 14 |
|
//main.cpp #include <QApplication> #include "mainwidget.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); MainWidget *mainWidget = new MainWidget; mainWidget->show(); //程序进入事件循环状态 return app.exec(); } |
11)程序只有在13行后进入事件循环状态,只有在这时才处理信号和事件。
(2) 信号与槽
1 2 3 4 5 6 |
|
//信号-槽连接 connect(sender, SIGNAL(signal), receiver, SLOT(slot)); //信号-信号连接 connect(sender, SIGNAL(signal), sender2, SIGNAL(signal2)); //连接移除 disconnect(sender, SIGNAL(signal), receiver, SLOT(slot)); |
1)一个信号可连接多个槽,当发射这个信号时,会以不确定的顺序一个接一个调用这些槽;
2)信号-信号连接时,当发射第一个信号,也会发射第二个信号;
3)连接的信号和槽的参数必须具有相同的顺序和相同的类型;这里有一个例外,如果信号的参数比它连接的槽的参数多时,多余的参数会忽略掉;