QT信号与槽

连接信号与槽

  • 接口
    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参数

enumdescription
Qt::AutoConnection自动连接:(默认值),使用此值,连接类型会在信号发射时决定。如果接收者和发送者在同一个线程,则自动使用Qt::DirectConnection类型,如果接收者和发送者不在同一个线程,则自动使用Qt::QueuedConnection类型。
Qt::DirectConnection直接连接:当信号发射时,槽函数立即直接调用。无论槽函数所属对象在哪个线程,槽函数总在发送者所在线程执行,即槽函数和信号发送者在同一线程。
Qt::QueuedConnection队列连接:当控制权回到接受者所依附线程的事件循环时,槽函数被调用。槽函数在接收者所依附线程执行。也就是说:这种方式既可以在线程内传递消息,也可以跨线程传递消息
Qt::BlockingQueuedConnection与Qt::QueuedConnection相同,只是在插槽返回之前信令线程会阻塞。如果接收方生活在发送信号的线程中,则不能使用此连接,否则应用程序将死锁。。
Qt::UniqueConnection这是一个标志,可以使用按位OR与上述任何一种连接类型组合。当Qt::UniqueConnection被设置时,如果连接已经存在,QObject::connect()将失败(例如,如果相同的信号已经连接到同一对对象的相同槽位)
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

复杂的世界311

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值