背景:多个信号需要执行同一个函数或者一类函数的时候,可以选择每个信号创建一个槽函数去实现功能,如果直接关联到一个函数中,该函数只能执行一份功能,有时候并不能满足业务需求
在多个信号绑定到同一个槽函数的状态下,让槽函数根据绑定的不同的信号执行不同的功能有两种方法:
(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