如何判断信号是谁发出的?

发布于 2024-10-11 07:34:19 字数 96 浏览 2 评论 0原文

我在 PyQt 上开发一个应用程序,我喜欢信号槽模型,但是有什么方法可以 确定信号的发射器?我希望有一种方法,因为它可以让我们编写更通用的代码,而无需为每个相似的信号定义大量槽。

I develop an application on PyQt, I like the signal-slot model, but is there any way to
determine the emitter of signal? I hope that there is a way, because it will let to write more generic code without defining lots of slots for each similar signal.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

清风无影 2024-10-18 07:34:19

我觉得我提问题太早了,因为我自己在google上找到了答案。
当槽被发射器激活时,发射器的指针被存储,并且可以通过以下方式检索

QObject::sender()

,因此可以在 PyQt 中通过以下方式访问:

@QtCore.pyqtSlot()
def someSlot(self):
    self.sender()

I think that I opened a question too early, because I found an answer on google by myself.
When slot is activated by emitter, the pointer of emitter stored, and can be retrieved by

QObject::sender()

and as a result can be accessed in PyQt by:

@QtCore.pyqtSlot()
def someSlot(self):
    self.sender()
ぇ气 2024-10-18 07:34:19

您可能需要查看 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 示例。

You might want to look into the QSignalMapper class, as it provides a means to associate either an int, string, or widget paramters to an object that sends a given signal. The main limitation is that the signal/slot being mapped needs to be parameter-less.

C++ example from the QT4.7 documentation:

 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);
 }

You can find a PyQT4 example here, however when I have a chance I'll try to add a simple PyQT4 example.

疯到世界奔溃 2024-10-18 07:34:19

Qt5 选项是使用信号映射器。它是一个能够从不同源接收信号并使用唯一参数调用单个回调函数(槽)的对象。然后该函数使用该参数来确定源。假设我们要将两个复选框连接到同一个插槽:

创建信号映射器:

signalMapper = QSignalMapper()

int 类型的映射与回调函数关联:

signalMapper.mapped[int].connect(sync_checkboxes)

将触发信号的小部件连接到映射器:

checkbox_1.clicked.connect(signalMapper.map)
checkbox_2.clicked.connect(signalMapper.map)

定义映射源和 int 值(0 和 1)之间:

signalMapper.setMapping(checkbox_1, 0)
signalMapper.setMapping(checkbox_2, 1)

现在回调接受整数值:

def sync_checkboxes(index):
    if index == 0:
        ....

文档(质量差):

映射可以是 void(传递源对象引用)、基于整数、基于字符串或基于对象。根据我对文档的理解,不同的类型可以混合,映射器识别哪个映射与源关联,并调用适当的回调。没有说明如果为同一个源设置了多个映射会发生什么,因此需要进行一些实验。遗憾的是,对于这样一个有趣的产品来说,文档太少了。

The Qt5 option is to use a signal mapper. It's an object able to receive a signal from different sources and call a single callback function (slot) with a unique parameter. The function then uses the parameter to determine the source. Let's say we want to connect two check boxes to the same slot:

Create a signal mapper:

signalMapper = QSignalMapper()

Associate a mapping of type int with the callback function:

signalMapper.mapped[int].connect(sync_checkboxes)

Connect the widgets triggering the signals to the mapper:

checkbox_1.clicked.connect(signalMapper.map)
checkbox_2.clicked.connect(signalMapper.map)

Define the mapping between the sources and the int values (0 and 1):

signalMapper.setMapping(checkbox_1, 0)
signalMapper.setMapping(checkbox_2, 1)

Now the callback accepting the integer value:

def sync_checkboxes(index):
    if index == 0:
        ....

Documentation (of poor quality):

The mapping can be void (source object reference is passed), integer-based, string-based or object-based. From what I understand from the documentation, the different types can be mixed, the mapper identifies which mapping is associated to the source, and calls the appropriate callback. What happens if multiple mappings have been set for the same source is not said, so some experiment is required. It's a pity the documentation is so poor for a such interesting product.

明月夜 2024-10-18 07:34:19

请注意,这不会告诉您例如。网格控件中的哪个单元格被编辑 - 仅网格控件句柄本身。

有一本新的 Advanced Qt 书,其中详细介绍了高级信号/槽路由

Note that this doesn't tell you eg. which cell in a grid control wasedited - just the grid control handle itself.

There is a new Advanced Qt book out which goes into a lot of detail about advanced signal/slot routing

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文