信号与槽可以实现两个对象之间的通信。例如:如果点击了关闭按钮,我们希望窗口调用close()函数退出。
信号与槽简单来说就是,一个事件发生会发出一个信号,收到这个信号后,会调用槽函数。下面看一个简单例子。
1.#include <mainwindow.h>
2.#include <QApplication>
3.#include <QPushButton>
4.#include <QDesktopWidget>
5.
6.int main(int argc, char *argv[])
7.{
8. QApplication a(argc, argv);
9. QWidget *widget = new QWidget;
10. QPushButton *button = new QPushButton("Quit",widget) ;
11. widget->resize(300,150);
12. button->move((widget->width()-button->width())/2,(widget->height()-button->height())/2);
13. button->setStyleSheet("background-color:rgba(242,141,102,255);");
14.
15. QObject::connect(button,SIGNAL(clicked(bool)),widget,SLOT(close()));//信号与槽
16.
17. widget->show();
18. int rec = a.exec() ;
19. delete widget ;
20. return rec ;
21.}
通过15行的QObject::connect()函数,当我们按下按钮button的时候,就会关闭widget窗口了。
它的函数原型如下
bool QObject::connect(const QObject * sender ,
const char * signal,
const QObject * receiver ,
const char * method , Qt::ConnectionTypetype=Qt::AutoConnection)
第一个参数是发送信号的对象,第二个参数是发送的信号,第三个参数是接受信号的对象,第四个参数是槽函数。
对于信号与槽,必须使用SIGNAL()和SLOT()宏,它们可以将其参数转化为const char *类型。conncet函数的返回值为bool类型,当关联成功时返回true。
注意:
信号与槽的参数只能有类型,不能有变量。
基本原则要求信号的参数类型和槽的参数类型一致。信号的参数个数可以多于槽,但不能反过来。
一个信号可以关联多个槽
多个信号可以关联一个槽
一个信号可以关联另一个信号
信号没有返回值,只能是void类型
自定义信号与槽
简单实现一个程序:在一个窗口中创建一个对话框,在这个对话框中可以输入数值,当单击“确定”按钮时关闭对话框并将对话框的数值通过信号发送出去,在另一个窗口中接收信号并显示该数值。
新建项目,基类选择QWidget,类名选择Widget不变。项目建立完成后,向项目中添加新文件,模板选择Qt中的“Qt设计师界面类”,界面模板选择“Dialog without Buttons”,类名选择MyDialog。完成后首先在mydialog.h中添加一个信号
信号只用声明,不需要也不能对它进行实现。声明信号用singals关键字,signals前不能加private、public、protect限定符。
在widget.h中加入自定义的槽
声明槽函数用slots关键字,slots前可以加private、public、protect限定符。
在mydialog.ui对应的界面中拖取一个PushButton 和一个Spinbox,控件名改为button和spinbox,button的text设置为“确定”。
右键确定按钮,选择“转到槽”,出现下图,选择clicked()。
点击OK。在出现的槽函数中加入如下代码
1.void MyDialog::on_button_clicked()
2.{
3. int value = ui->spinbox->value() ;
4. emit ValueReturn(value) ;//发送信号用emit关键字
5. close();
6.}
打开widget.ui界面,向界面上拖取一个Label控件,大小可调。然后往widget.cpp中加入 “mydialog.h”头文件,再往构造函数中加入如下代码
1.MyDialog *dialog = new MyDialog(this) ;
2.QObject::connect(dialog,SIGNAL(ValueReturn(int)),this,SLOT(ShowValue(int)));
dialog->show();
在widget.cpp定义槽函数ShowValue(int)
1.void Widget::ShowValue(int value)
2.{
3. ui->label->setText(trUtf8("获取的值是:%1").arg(value));
4.}
运行,在微调框中输入50。
点击确定。