使用新式语法连接重载的 PyQT 信号

Posted

技术标签:

【中文标题】使用新式语法连接重载的 PyQT 信号【英文标题】:Connecting an overloaded PyQT signal using new-style syntax 【发布时间】:2018-12-31 10:44:20 【问题描述】:

我正在设计一个自定义小部件,它基本上是一个 QGroupBox,其中包含可配置数量的 QCheckBox 按钮,其中每个按钮都应控制表示的位掩码中的特定位通过QBitArray。为了做到这一点,我将 QCheckBox 实例添加到 QButtonGroup,每个按钮都给定一个整数 ID:

    def populate(self, num_bits, parent = None):
        """
        Adds check boxes to the GroupBox according to the bitmask size
        """
        self.bitArray.resize(num_bits)
        layout = QHBoxLayout()

        for i in range(num_bits):
            cb = QCheckBox()
            cb.setText(QString.number(i))
            self.buttonGroup.addButton(cb, i)
            layout.addWidget(cb)
        self.setLayout(layout)

然后,每次用户单击 self.buttonGroup 中包含的复选框时,我希望 self.bitArray 得到通知,以便在可以相应地设置/取消设置数组。为此,我打算将 QButtonGroup's buttonClicked(int) 信号连接到 QBitArray's toggleBit(int) 方法,然后尽可能 Pythonic,我想使用新式的信号语法,所以我尝试了这个:

self.buttonGroup.buttonClicked.connect(self.bitArray.toggleBit)

问题在于 buttonClicked 是一个重载信号,所以还有 buttonClicked(QAbstractButton*) 签名。事实上,当程序执行时,当我单击复选框时会出现此错误:

The debugged program raised the exception unhandled TypeError
"QBitArray.toggleBit(int): argument 1 has unexpected type 'QCheckBox'"

这清楚地表明 toggleBit 方法收到了 buttonClicked(QAbstractButton*) 信号,而不是 buttonClicked(int) 信号。

那么,问题是,如何指定信号连接,使用新式语法,以便 self.bitArray 接收 buttonClicked(int ) 信号而不是默认的重载 - buttonClicked(QAbstractButton*)?

编辑:PyQT's New-style Signal and Slot Support documentation 声明您可以使用 pyqtSlot 装饰器来指定要连接到给定插槽的信号,但这是针对您的插槽创造。当插槽来自“现成”类时该怎么办?唯一的选择是继承它,然后用正确的装饰器重新实现给定的插槽?

【问题讨论】:

【参考方案1】:

在浏览相关问题时,我发现this answer 正是我所需要的。仅将 QButtonGroup's buttonClicked(int) 信号连接到 QBitArray's toggleBit(int) 的正确新型信号语法,忽略其他重载签名,涉及在括号中指定所需的类型,如下所示:

self.buttonGroup.buttonClicked[int].connect(self.bitArray.toggleBit)

【讨论】:

以上是关于使用新式语法连接重载的 PyQT 信号的主要内容,如果未能解决你的问题,请参考以下文章

PyQt_PyObject在使用新式信号/插槽时是等价的吗?

Nginx命令行及演示:重载热部署日志切割

Qt 拾遗 003 disconnect

Qt信号槽原理(链接)

使用重载的 PySide 信号调用 Python 函数而不传递参数

C++运算符重载学习总结