一、简介
信号和槽是Qt的核心特征。用于对象间的通信,类似观察者模式。例如当一个按钮被点击,按钮监测到自己被点击了一下,就会发送一个信号(signal)。这个信号无目的,类似广播。如果我们需要处理这个信号,那么就需要使用connect来连接一个对象,使用该对象对应的槽函数(slot)来处理这个信号。也就是说,当点击按钮时,会触发与之相关联的槽函数。一个信号可以关联多个槽函数,多个信号也可以关联到一个槽函数上,甚至一个信号还可以关联到另一个信号上。当信号被发射时,这些关联的槽会一个接一个的执行,但是执行顺序是随机的,无法指定执行顺序。另外,槽函数的参数可以少于信号的参数,但是不能多于信号的参数。
二、示例
1. 在mainwindow.h中声明一个私有变量label,和一个槽
class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private slots: void on_pushButton_clicked(); private: Ui::MainWindow *ui; QLabel *label; };
2.在mainwindow.cpp中
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); label = new QLabel(this); label->setText(tr("this is label")); label->move(100,100); QPushButton *btn = new QPushButton(this); btn->setGeometry(100,150,200,40); btn->setText(tr("change label text")); connect(btn,SIGNAL(clicked()),this,SLOT(on_pushButton_clicked())); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_pushButton_clicked() { label->setText(tr("clicked button")); }
运行程序,当点击按钮后,label的显示内容就发生了改变。
三、自定义信号槽
其实上面的例子里,我们已经自定义了槽。自定义信号也很简单,只需要在发送信号的对象中声明一个信号,不用实现。例如在mainwindow.h中添加如下代码
signals: void changeLabelTxt();
这样便在mainwindow中自定义了一个信号,然后在需要发送的信号的地方调用emit发送即可。
emit changeLabelTxt();
然后在接收信号的对象中,调用connect函数连接槽。
自定义信号槽有几点需要注意:
- 必须继承自QObject或其子类
- 在类声明的最开始处添加Q_OBJECT宏
- 槽函数中的参数类型要与信号中的参数类型相对应,且数量不能比信号多。信号的参数个数可以比槽多,多出来的会弃用
- 信号只有声明,没有定义。返回值类型为void