Qt 多个信号关联同一个槽函数

2023-02-26  本文已影响0人  hao_developer

背景:多个信号需要执行同一个函数或者一类函数的时候,可以选择每个信号创建一个槽函数去实现功能,如果直接关联到一个函数中,该函数只能执行一份功能,有时候并不能满足业务需求

在多个信号绑定到同一个槽函数的状态下,让槽函数根据绑定的不同的信号执行不同的功能有两种方法:

(1)在槽函数中获取到sender对象,反向解析出信号的名称,分叉执行;

(2)使用QSingalMapper类:管理多个信号,槽函数的处理相对变得简单。

具体来看:

(1)反向获取Sender名称

关键函数:

QObject::sender()                  // 在槽函数中获取信号
QObject::setObjectName(QString)    // 给QObject对象设置名称
QObject::objectName()              // 获取QObject对象名称
QObject_cast<QObject>(object)      // 强转对象类型

思路如下:


image.png

示例代码如下:

 typedef enum{
   BUTTON_1,
   BUTTON_2,
   BUTTON_3,
   BUTTON_4
 }BUTTON;
 push_button_1->setObjectName(QString::number(BUTTON_1, 10));
 push_button_2->setObjectName(QString::number(BUTTON_2, 10));
 tool_button_1->setObjectName(QString::number(BUTTON_3, 10));
 tool_button_2->setObjectName(QString::number(BUTTON_4, 10));
 connect(push_button_1, &QPushButton::clicked, this, &MyWidget::changeButton);
 connect(push_button_2, &QPushButton::clicked, this, &MyWidget::changeButton);
 connect(tool_button_1, &QToolButton::clicked, this, &MyWidget::changeButton);
 connect(tool_button_2, &QToolButton::clicked, this, &MyWidget::changeButton);
  
void MyWidget::changeButton()
{
  QObject *object = QObject::sender();
  QPushButton *push_button = qobject_cast<QPushButton *>(object);
  QToolButton *tool_button = qobject_cast<QToolButton *>(object);
  int index;
  if(push_button)
  {
     QString object_name = push_button->objectName();
     index = object_name.toInt();
  }
  else if(tool_button )
  {
     QString object_name = tool_button->objectName();
     index = object_name.toInt();
  }
 
  QString information = QString("");
  switch(index)
  {
    case BUTTON_1:
      information = QString("clicked 1");
      break;

    case BUTTON_2:
      information = QString("clicked 2");
      break;
  
    case BUTTON_3:
      information = QString("clicked 3");
      break;

    case BUTTON_4:
      information = QString("clicked 4");
      break;

  default:
      information = QString("which is clicked?");
     break;
  }
  QMessageBox::information(NULL, QString("Title"), information);
 }

( 2 ) 使用QSignalMapper类

这个思想是:希望能够在信号关联中直接传递一个参数!直接用信号槽无法实现

QSignalMapper类内置了一个Map表,将Singnal和参数对应起来,然后多个信号关联到Mapper上,由mapper负责管理,并且mapper关联到槽函数中,将对应的参数传入槽函数

这个流程图如下:


image.png

实例代码如下:

QSignalMapper *signal_mapper = new QSignalMapper(this);
connect(push_button_1, &QPushButton::clicked, signal_mapper, &QSignalMapper::map);
connect(push_button_2, &QPushButton::clicked, signal_mapper, &QSignalMapper::map);
connect(tool_button_1, &QToolButton::clicked, signal_mapper, &QSignalMapper::map);
connect(tool_button_2, &QToolButton::clicked, signal_mapper, &QSignalMapper::map);
 
signal_mapper->setMapping(push_button_1, QString::number(BUTTON_1, 10));
signal_mapper->setMapping(push_button_2, QString::number(BUTTON_2, 10));
signal_mapper->setMapping(tool_button_1, QString::number(BUTTON_3, 10));
signal_mapper->setMapping(tool_button_2, QString::number(BUTTON_4, 10));
connect(signal_mapper, &QSignalMapper::mapped, this, &MyWidget::changeButton);
 
void MyWidget::changeButton(QString text)
{
     int index = text.toInt();
     QString information = QString("");
     switch(index)
     {
     case BUTTON_1:
         information = QString("clicked 1");
         break;
  
     case BUTTON_2:
         information = QString("clicked 2");
         break;
  
     case BUTTON_3:
         information = QString("clicked 3");
         break;
  
     case BUTTON_4:
         information = QString("clicked 4");
         break;
  
     default:
         information = QString("which is clicked?");
         break;
     }
     QMessageBox::information(NULL, QString("Title"), information);
 }
上一篇 下一篇

猜你喜欢

热点阅读