连接信号与槽
-
接口
QObject::connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type = Qt::AutoConnection)
QT中绑定信号与槽的方式有两种:
其一:
connect(sender, SIGNAL(signal), receiver, SLOT(slot));
其二:
connect(sender, &Sender::signal, receiver, &Receiver::slot);
前者是QT5之前的写法,后者是QT5出现的写法。使用第一种方式去进行连接信号与槽时容易signal或者slot接口写错出现在触发信号后没有进入对应的槽函数。使用第二种方式会检查信号与槽是否存在因此不会出现上述问题,以及支持lambda表达式。 -
使用
1、方式一
connect(ui->spinBox,SIGNAL(valueChanged(int)),this, SLOT(spinValueChange(int)));
2、方式二
使用方式二如果没有重载函数的情况下比较简单直接取对应signal和slot函数地址就好
connect(sender, &Sender::signal, receiver, &Receiver::slot);
当存在重载的情况下可以使用QOverload、函数指针,类型强制转换三种方式去进行使用,具体使用如下:
QOverload:
connect(sender, QOverload<bool>::of(&Sender::signal),receiver,
QOverload<bool>::of(&Receiver::slot));
函数指针:
void (Sender:: * ptr)(int) = &Sender::signal;
void (Receiver:: *rptr)(int) = &Receiver::slot;
connect(sender,ptr,receiver,rptr);
static_cast:
connect(sender, static_cast<void(Sender::*)(bool)>(&Sender::signal),
receiver, static_cast<void(Receiver::*)(void)>(&Receiver::slot));
断开连接disconnect
- 使用
disconnect(push_button); //断开push_button的所有连接
disconnect(push_button, &QPushButton::clicked, this, &QWidget::show); //断开此信号连接的槽
disconnect(myObject, 0, 0, 0);//断开所有连接到该对象的信号
disconnect(myObject, &MyObject::mySignal(), 0, 0);//断开一切连接到特定信号
disconnect(myObject, 0, myReceiver, 0);//断开一个特定的接收者
.....
其他使用可参考qt助手
多个信号绑定一个槽函数进行区分发送信号对象
- 使用objectName
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->pushButton->setObjectName(QString("1"));
ui->pushButton_2->setObjectName(QString("2"));
ui->pushButton_3->setObjectName(QString("3"));
ui->pushButton_4->setObjectName(QString("4"));
connect(ui->pushButton, QOverload<bool>::of(&QPushButton::clicked), this, &MainWindow::changeButton);
connect(ui->pushButton_2, QOverload<bool>::of(&QPushButton::clicked), this, &MainWindow::changeButton);
connect(ui->pushButton_3, QOverload<bool>::of(&QPushButton::clicked), this, &MainWindow::changeButton);
connect(ui->pushButton_4, QOverload<bool>::of(&QPushButton::clicked), this, &MainWindow::changeButton);
}
void MainWindow::changeButton(bool status)
{
QObject *object = QObject::sender();
QPushButton *push_button = qobject_cast<QPushButton *>(object);
int index = push_button->objectName().toInt();
QString str;
switch(index)
{
case 1:
str = QString("clicked 1");
break;
case 2:
str = QString("clicked 2");
break;
case 3:
str = QString("clicked 3");
break;
case 4:
str = QString("clicked 4");
break;
}
QMessageBox::information(NULL, QString("Title"), str);
}
- 使用QSignalMapper
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
signal_mapper = new QSignalMapper(this);
connect(ui->pushButton, QOverload<bool>::of(&QPushButton::clicked), signal_mapper,QOverload<void>::of(&QSignalMapper::map));
connect(ui->pushButton_2, SIGNAL(clicked(bool)), signal_mapper, SLOT(map()));
connect(ui->pushButton_3, SIGNAL(clicked(bool)), signal_mapper, SLOT(map()));
connect(ui->pushButton_4, static_cast<void(QPushButton::*)(bool)>(&QPushButton::clicked),
signal_mapper, static_cast<void(QSignalMapper::*)(void)>(&QSignalMapper::map));
signal_mapper->setMapping(ui->pushButton, QString::number(1, 10));
signal_mapper->setMapping(ui->pushButton_2, QString::number(2, 10));
signal_mapper->setMapping(ui->pushButton_3, QString::number(3, 10));
signal_mapper->setMapping(ui->pushButton_4, QString::number(4, 10));
connect(signal_mapper, SIGNAL(mapped(QString)), this, SLOT(changeButton(QString)));
}
void MainWindow::changeButton(QString info)
{
int index = info.toInt();
QString str;
switch(index)
{
case 1:
str = QString("clicked 1");
break;
case 2:
str = QString("clicked 2");
break;
case 3:
str = QString("clicked 3");
break;
case 4:
str = QString("clicked 4");
break;
}
QMessageBox::information(NULL, QString("Title"), str);
}
以上两种方式都能达到区分哪个butoom发出的信号效果。效果如下:
以下是Qt中对其的描述:
QSignalMapper类捆绑来自可识别发送者的信号。该类收集一组无参数信号,并使用与发送信号的对象对应的整数、字符串或小部件参数重新发出这些信号。该类支持使用setMapping()将特定字符串或整数与特定对象进行映射。然后对象的信号可以连接到map()插槽,该插槽将发射带有与原始信号发送对象关联的字符串或整数的mapped()信号。
Qt::ConnectionType参数
enum | description |
---|---|
Qt::AutoConnection | 自动连接:(默认值),使用此值,连接类型会在信号发射时决定。如果接收者和发送者在同一个线程,则自动使用Qt::DirectConnection类型,如果接收者和发送者不在同一个线程,则自动使用Qt::QueuedConnection类型。 |
Qt::DirectConnection | 直接连接:当信号发射时,槽函数立即直接调用。无论槽函数所属对象在哪个线程,槽函数总在发送者所在线程执行,即槽函数和信号发送者在同一线程。 |
Qt::QueuedConnection | 队列连接:当控制权回到接受者所依附线程的事件循环时,槽函数被调用。槽函数在接收者所依附线程执行。也就是说:这种方式既可以在线程内传递消息,也可以跨线程传递消息 |
Qt::BlockingQueuedConnection | 与Qt::QueuedConnection相同,只是在插槽返回之前信令线程会阻塞。如果接收方生活在发送信号的线程中,则不能使用此连接,否则应用程序将死锁。。 |
Qt::UniqueConnection | 这是一个标志,可以使用按位OR与上述任何一种连接类型组合。当Qt::UniqueConnection被设置时,如果连接已经存在,QObject::connect()将失败(例如,如果相同的信号已经连接到同一对对象的相同槽位) |