QT_C++_信号与槽
Qt 信号与槽机制
槽(Slot)就是对信号响应的函数。槽就是一个函数,与一般的 C++函数是一样的,可以定义在类的任何部分(public、private 或 protected),可以具有任何参数,也可以被直接调用。槽函数与一般的函数不同的是:槽函数可以与一个信号关联,当信号被发射时,关联的槽函数被自动执行。信号与槽关联是用 QObject::connect() 函数实现的,其基本格式是:
QObject::connect(sender, SIGNAL(signal()), receiver, SLOT(slot()));
connect() 是 QObject 类的一个静态函数,而 QObject 是所有 Qt 类的基类,在实际调用时可以忽略前面的限定符,所以可以直接写为:
connect(sender, SIGNAL(signal()), receiver, SLOT(slot()));
其中,sender 是发射信号的对象的名称,signal() 是信号名称。信号可以看做是特殊的函数,需要带括号,有参数时还需要指明参数。receiver 是接收信号的对象名称,slot() 是槽函数的名称,需要带括号,有参数时还需要指明参数。SIGNAL 和 SLOT 是 Qt 的宏,用于指明信号和槽,并将它们的参数转换为相应的字符串。
举例:
QObject::connect(pushButton, SIGNAL(clicked()), MainWindow, SLOT(close()));
其作用就是将 pushButton 按钮的 clicked() 信号与窗体(MainWindow)的槽函数 close() 相关联。
一个信号可以连接多个槽,例如:
connect(pushButton, SIGNAL(clicked()), this, SLOT(hide());
connect(pushButton, SIGNAL(clicked()), this, SLOT(close());
这是当一个对象 pushButton 的被单击时,所在窗体有两个槽进行响应,一个 hide()用于隐藏主窗体,一个 close 用于关闭主窗体。
多个信号可以连接同一个槽,例如:
connect(pushButton,SIGNAL(clicked()),this,SLOT(close()));
connect(pushButton_2,SIGNAL(clicked()),this,SLOT(close()));
connect(pushButton_3,SIGNAL(clicked()),this,SLOT(close()));
一个信号可以连接另外一个信号(说明了 connect 万物皆可连,非常好用!),例如:
connect(pushButton, SIGNAL(objectNameChanged(QString)),this, SIGNAL(windowTitelChanged(QString)));
注意:
1、严格的情况下,信号与槽的参数个数和类型需要一致,至少信号的参数不能少于槽的参数。如果不匹配,会出现编译错误或运行错误。
2、在使用信号与槽的类中,必须在类的定义中加入宏 Q_OBJECT(特别重要)。
3、当一个信号被发射时,与其关联的槽函数通常被立即执行,就像正常调用一个函数一样。只有当信号关联的所有槽函数执行完毕后,才会执行发射信号处后面的代码。
说明:可以看到发送者与发送的信号是在一起的,接收者与接收的信号/槽是在一起的。它们不能在
connect()方法里写乱顺序!由发送者发送出信号到接收者用信号/槽接收。
如何在项目里创建信号
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QPushButton>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
signals:
void pushButtonTextChanged();
public slots:
/* 声明一个槽函数 */
void changeButtonText();
/* 声明按钮点击的槽函数 */
void pushButtonClicked();
private:
/* 声明一个对象 pushButton */
QPushButton *pushButton;
};
#endif // MAINWINDOW_H
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.cpp
#include "mainwindow.h"
#include "qdebug.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
this->resize(800, 480);
pushButton = new QPushButton(this);
pushButton->setText("按钮");
connect(pushButton, SIGNAL(clicked()), this, SLOT(pushButtonClicked()));
connect(this, SIGNAL(pushButtonTextChanged()), this, SLOT(changeButtonText()));
}
MainWindow::~MainWindow()
{
}
void MainWindow::changeButtonText()
{
qDebug("1123");
pushButton->setText("被点击了");
}
void MainWindow::pushButtonClicked()
{
qDebug("123");
emit pushButtonTextChanged();
}
补充:
Qt 里有大量的信号与槽,都是 Qt 自定义好的。基本够我们使用,如果没有找到想要的信号与槽,我们就可以按 5.2~5.4 小节自定义信号与槽的方法去定义自己的信号和槽了。