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

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

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

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

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

具体来看:

(1)反向获取Sender名称

关键函数:

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

思路如下:

示例代码如下:

 1 typedef enum{
 2 BUTTON_1,
 3 BUTTON_2,
 4 BUTTON_3,
 5 BUTTON_4
 6 }BUTTON;
 7  
 8  push_button_1->setObjectName(QString::number(BUTTON_1, 10));
 9  push_button_2->setObjectName(QString::number(BUTTON_2, 10));
10  tool_button_1->setObjectName(QString::number(BUTTON_3, 10));
11  tool_button_2->setObjectName(QString::number(BUTTON_4, 10));
12  connect(push_button_1, &QPushButton::clicked, this, &MyWidget::changeButton);
13  connect(push_button_2, &QPushButton::clicked, this, &MyWidget::changeButton);
14  connect(tool_button_1, &QToolButton::clicked, this, &MyWidget::changeButton);
15  connect(tool_button_2, &QToolButton::clicked, this, &MyWidget::changeButton);
16  
17 void MyWidget::changeButton()
18 {
19     QObject *object = QObject::sender();
20     QPushButton *push_button = qobject_cast<QPushButton *>(object);
21     QToolButton *tool_button = qobject_cast<QToolButton *>(object);
22     int index;
23     if(push_button)
24     {
25         QString object_name = push_button->objectName();
26         index = object_name.toInt();
27     }
28     else if(tool_button )
29     {
30          QString object_name = tool_button->objectName();
31          index = object_name.toInt();
32     }
33  
34     QString information = QString("");
35     switch(index)
36     {
37     case BUTTON_1:
38         information = QString("clicked 1");
39         break;
40  
41     case BUTTON_2:
42         information = QString("clicked 2");
43         break;
44  
45     case BUTTON_3:
46         information = QString("clicked 3");
47         break;
48  
49     case BUTTON_4:
50         information = QString("clicked 4");
51         break;
52  
53     default:
54         information = QString("which is clicked?");
55         break;
56     }
57     QMessageBox::information(NULL, QString("Title"), information);
58 }

( 2 )  使用QSignalMapper类

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

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

这个流程图如下:

 

实例代码如下:

 1 QSignalMapper *signal_mapper = new QSignalMapper(this);
 2 connect(push_button_1, &QPushButton::clicked, signal_mapper, &QSignalMapper::map);
 3 connect(push_button_2, &QPushButton::clicked, signal_mapper, &QSignalMapper::map);
 4 connect(tool_button_1, &QToolButton::clicked, signal_mapper, &QSignalMapper::map);
 5 connect(tool_button_2, &QToolButton::clicked, signal_mapper, &QSignalMapper::map);
 6  
 7 signal_mapper->setMapping(push_button_1, QString::number(BUTTON_1, 10));
 8 signal_mapper->setMapping(push_button_2, QString::number(BUTTON_2, 10));
 9 signal_mapper->setMapping(tool_button_1, QString::number(BUTTON_3, 10));
10 signal_mapper->setMapping(tool_button_2, QString::number(BUTTON_4, 10));
11 connect(signal_mapper, &QSignalMapper::mapped, this, &MyWidget::changeButton);
12  
13 void MyWidget::changeButton(QString text)
14 {
15     int index = text.toInt();
16     QString information = QString("");
17     switch(index)
18     {
19     case BUTTON_1:
20         information = QString("clicked 1");
21         break;
22  
23     case BUTTON_2:
24         information = QString("clicked 2");
25         break;
26  
27     case BUTTON_3:
28         information = QString("clicked 3");
29         break;
30  
31     case BUTTON_4:
32         information = QString("clicked 4");
33         break;
34  
35     default:
36         information = QString("which is clicked?");
37         break;
38     }
39     QMessageBox::information(NULL, QString("Title"), information);
40 }
41 20/article/details/81016424
原文地址:https://www.cnblogs.com/ybqjymy/p/14636903.html