如何确定是谁发出了信号?
我在用PyQt开发一个应用程序,我很喜欢信号和槽的模型。但是,有没有办法知道哪个地方发出了信号呢?我希望能有这样的办法,因为这样可以让我写出更通用的代码,而不用为每个类似的信号定义很多个槽。
4 个回答
0
在Qt5中,有一个选项是使用信号映射器。它是一个可以接收来自不同来源的信号的对象,并且可以用一个独特的参数调用一个单一的回调函数(也叫槽)。这个函数会使用这个参数来判断信号的来源。比如说,我们想把两个复选框连接到同一个槽:
首先,创建一个信号映射器:
signalMapper = QSignalMapper()
然后,把一个类型为int
的映射和回调函数关联起来:
signalMapper.mapped[int].connect(sync_checkboxes)
接着,把触发信号的控件连接到映射器:
checkbox_1.clicked.connect(signalMapper.map)
checkbox_2.clicked.connect(signalMapper.map)
定义来源和整数值(0和1)之间的映射关系:
signalMapper.setMapping(checkbox_1, 0)
signalMapper.setMapping(checkbox_2, 1)
现在,回调函数可以接受这个整数值:
def sync_checkboxes(index):
if index == 0:
....
文档(质量不太好):
- 信号映射器:QSignalMapper
- 接收信号的槽:QSignalMapper.map()
- 带有整数参数的信号:QSignalMapper.mapped[int]()
这个映射可以是空的(传递源对象的引用),也可以是基于整数、字符串或对象的。根据我从文档中理解的,不同类型的映射可以混合使用,映射器会识别哪个映射与来源相关,并调用相应的回调。不过,对于同一个来源设置多个映射会发生什么,文档没有说明,所以需要一些实验来验证。可惜的是,这么有趣的产品文档质量却这么差。
1
你可能想了解一下 QSignalMapper 这个类,因为它可以帮助你把一个整数、字符串或者小部件的参数和发送特定信号的对象关联起来。主要的限制是,被映射的信号和槽(也就是处理信号的函数)必须没有参数。
下面是来自 QT4.7 文档 的 C++ 示例:
ButtonWidget::ButtonWidget(QStringList texts, QWidget *parent)
: QWidget(parent)
{
signalMapper = new QSignalMapper(this);
QGridLayout *gridLayout = new QGridLayout;
for (int i = 0; i < texts.size(); ++i) {
QPushButton *button = new QPushButton(texts[i]);
connect(button, SIGNAL(clicked()), signalMapper, SLOT(map()));
signalMapper->setMapping(button, texts[i]);
gridLayout->addWidget(button, i / 3, i % 3);
}
connect(signalMapper, SIGNAL(mapped(const QString &)),
this, SIGNAL(clicked(const QString &)));
setLayout(gridLayout);
}
你可以在这里找到一个 PyQT4 的示例 这里,不过当我有机会的时候,我会尝试添加一个简单的 PyQT4 示例。
29
我觉得我提问的时间有点早,因为我自己在谷歌上找到了答案。
当发射器(emitter)激活插槽(slot)时,发射器的指针会被存储下来,可以通过下面的代码获取:
QObject::sender()
因此,在PyQt中可以通过以下方式访问:
@QtCore.pyqtSlot()
def someSlot(self):
self.sender()