python - 与装饰器一起使用时 pyqt 信号的问题

标签 python pyqt pyqt5

当使用 UI 元素(例如带有装饰方法的按钮)的 pyqt 信号时,该信号似乎不起作用。请在下面找到最低可重现代码。

import sys
from PyQt5.QtWidgets import (QWidget, QToolTip, QPushButton, QApplication)
from PyQt5.QtGui import QFont

def ui_decorator(target_func):
    def call(self, *args, **kwargs):
        print("Init.")
        ret_code = target_func(self, *args, **kwargs)
        print("Deinit.")
        return ret_code
    return call

class Example(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        QToolTip.setFont(QFont('SansSerif', 10))
        self.setToolTip('This is a <b>QWidget</b> widget')
        btn = QPushButton('Button', self)
        btn.setToolTip('This is a <b>QPushButton</b> widget')
        btn.clicked.connect(self.button_action)
        btn.resize(btn.sizeHint())
        btn.move(50, 50)

        self.setGeometry(300, 300, 300, 200)
        self.setWindowTitle('Tooltips')
        self.show()

    @ui_decorator
    def button_action(self):
        print("Button Clicked")

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

在上面的代码中,如果单击按钮,则对 button_action 函数的调用将失败,并显示以下消息:TypeError:button_action() 需要 1 个位置参数,但给出了 2 个。但是当我不使用装饰器 (ui_decorator) 时,代码可以正常工作,即使它仍然只需要 1 个位置参数。

谢谢

最佳答案

当 PyQt 调用一个槽(可以是任何可调用的)时,它不仅仅是“调用”它。为了实现忽略附加槽参数的行为,它分析可调用对象并仅传递适当数量的参数。通过让装饰器返回一个接受任意数量参数的可调用函数,并将所有参数简单地传递给实际函数,您可以使该机制变得毫无用处。

您有两个选择:

  • 调整您的装饰器,使其返回一个可调用的对象,该可调用对象接受正确数量的参数(我怀疑这相当困难)。
  • 使用PyQt pyqtSlot decorator在你自己的装饰器之上。该装饰器定义了插槽的签名,并使上述行为再次起作用,因为 PyQt 知道该插槽没有参数:
@pyqtSlot()
@ui_decorator
def button_action(self):
    print("Button Clicked")

关于python - 与装饰器一起使用时 pyqt 信号的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70439144/

相关文章:

Python运行命令行(时间)

python - 如何从 Python 日志记录模块获取非阻塞/实时行为? (输出到 PyQt QTextBrowser)

pyqt - 在 pyqt 中禁用 QComboBox

python - 如何将 Pika 与 Qt 集成?

python - Heroku 和 Amazon S3 上的 Django 压缩器错误 "UncompressableFileError"

Python用完整列表填充列表中缺失的条目

python - sudo pip 安装 django

python - 如何获取 `QMainWindow`的屏幕位置并打印出来?

python - 单击 QPushButton 时,它会触发两次

python - 位置权限弹出窗口