在Qt中使用信号和槽机制来完成对象之间的协同操作。
简单来说,信号和槽都是函数,比如按下窗口上的一个按钮后想要改变一个窗口上label的文字,那么就可以将这个按钮的单击信号和我们定义的槽关联起来,在槽中中修改label上的文字。这样,当单击这个按钮时就会发射信号,进而执行我们的槽来修改文字。
信号与槽的三种关联方式:
- 使用connect()关联
- 设计模式中关联
- 自动关联
关联方式一:使用connect()关联
实例代码:
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private:
Ui::Widget *ui;
private slots:
void showChildDialog(); //槽声明
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
connect(ui->pushButtonOn, SIGNAL(clicked()), //实现信号与槽的连接
this, SLOT(showChildDialog()));
}
Widget::~Widget()
{
delete ui;
}
void Widget::showChildDialog() //槽实现
{
ui->labelOn->setText("PushButtonConnectClicked");
ui->labelOn->resize(20,30);
}
说明:
这里自定义了一个槽,槽一般使用slots关键字进行修饰(Qt 4中必须使用,Qt 5使用新connect语法时可以不用,为了与一般函数进行区别,建议使用),这里使用了private slots,表明这个槽不可以在类外被调用。
clicked()信号在QPushButton类中进行了定义,而connect()是QObject类中的函数,因为我们的类继承自QObject,所以可以直接使用它。
connect函数原型:
QMetaObject::Connection connect(const QObject * sender, const char * signal,
const char * method, Qt::ConnectionType type = Qt::AutoConnection) const
connect()函数中的四个参数分别是:发送信号的对象、发送的信号、接收信号的对象和要执行的槽。
当指定信号signal时必须使用QT的宏SIGNAL(),当指定槽函数时必须使用宏SLOT()。如果发射者和接收者属于同一个对象的话,那么在connect调用中接收者参数能省略。
关联方式二:在设计模式关联
首先添加自定义对话框类MyDialog。在设计模式中向窗口上添加两个Push Button,并且分别更改其显示文本为“进入主界面”和“退出程序”。
点击设计器上方的“编辑信号/槽”图标,或者按下快捷键F4,这时便进入了部件的信号和槽的编辑模式。在“退出程序”按钮上按住鼠标左键,然后拖动到窗口界面上,这时松开鼠标左键。
在弹出的配置连接对话框中,选中下面的“显示从QWidget继承的信号和槽”选项,然后在左边的QPushButton栏中选择信号clicked(),在右边的QDialog栏中选择对应的槽close(),完成后按下“确定”。
关联方式三:自动关联
在“进入主界面”按钮上右击,在弹出的菜单上选择“转到槽”,然后在弹出的对话框中选择clicked()信号,并按“确定”。这时便会进入代码编辑模式,并且定位到自动生成的on_pushButton_clicked()槽中。在其中添加代码:
会自动生成函数:
void MyDialog::on_pushButton_clicked()
{
//里面的就可以自己填充
}
自动关联就是将关联函数整合到槽命名中。
例如on_pushButton_clicked()就是由字符“on”和发射信号的部件对象名,还有信号名组成。这样就可以去掉那个connect()关联函数了。每当pushButton被按下,就会发射clicked()信号,然后就会执行on_pushButton_clicked()槽。
这里accept()函数是QDialog类中的一个槽,对于一个使用exec()函数实现的模态对话框,执行了这个槽,就会隐藏这个模态对话框,并返回QDialog::Accepted值,我们就是要使用这个值来判断是哪个按钮被按下了。与其对应的还有一个reject()槽,它可以返回一个QDialog::Rejected值。其实,前面的“退出程序”按钮也可以关联这个槽。
断开联系
当信号和槽没有必要继续保持关联时,我们能使用disconnect函数来断开连接。其定义如下:
bool QObject::disconnect ( const QObject * sender, const char * signal,
const Object * receiver, const char * member ) [static]
这个函数断开发射者中的信号和接收者中的槽函数之间的关联。
有三种情况必须使用disconnect()函数:
(1)断开和某个对象相关联的所有对象。这似乎有点不可理解,事实上,当我们在某个对象中定义了一个或多个信号,这些信号和另外若干个对象中的槽相关联,如果我们要切断这些关联的话,就能利用这个方法,非常之简洁
disconnect( myObject, 0, 0, 0 ) 或 myObject->disconnect()
(2)断开和某个特定信号的所有关联。
disconnect( myObject, SIGNAL(mySignal()), 0, 0 ) 或 myObject->disconnect( SIGNAL(mySignal()) )
(3)断开两个对象之间的关联。
disconnect( myObject, 0, myReceiver, 0 ) 或 myObject->disconnect( myReceiver )
在disconnect函数中0能用作一个通配符,分别表示所有信号、所有接收对象、接收对象中的所有槽函数。不过发射者sender不能为0,其他三个参数的值能等于0。
参考:
https://blog.csdn.net/michealtx/article/details/6858784
https://www.cnblogs.com/liushui-sky/p/5732931.html