【问题标题】:PyQt auto slots: not called when decorated with a wrapperPyQt 自动插槽:用包装器装饰时不调用
【发布时间】:2015-04-27 01:11:01
【问题描述】:

我有一个通过 Qt Designer 创建的 QWidget,它有一个名为 fooQPushButtonQWidget 有一个名为 on_foo_clicked 的方法:

class MyWidget(QWidget):
    def __init__(self):
        ...
    @pyqtSlot()
    def on_foo_clicked(self):
        pass

首先,on_foo_clicked 只有在用pyqtSlot() 装饰时才会被调用。如果我删除那个装饰器,我必须在MyWidget 的初始化程序中手动将self.ui.fooQPushButton 类型)连接到self.on_foo_clicked,但我找不到任何关于此的文档。

其次,如果我想像这样使用自己的装饰器:

def auto_slot(func):
    @pyqtSlot()
    def wrapper(self):
        func(self)
    return wrapper

...

@auto_slot
def on_foo_clicked(self):
    pass

它不再起作用了。但以下工作:

def auto_slot(func):
    return pyqtSlot()(func)

所以问题不是 pyqtSlot 被另一个装饰器替换,而是由于某种原因 wrapper 函数导致自动连接机制失败。请注意,上述问题仅影响 自动 连接;如果我在MyWidget.__init__ 中添加一行以明确地将self.ui.foo 按钮连接到self.on_foo_clicked,那么带有wrapperauto_slot 装饰器将按预期工作,并且在单击按钮时调用该方法。

如果有什么我可以对auto_slotwrapper 做的事情,以便即使使用自动连接的插槽也能工作,有什么想法吗?

我想要这样做的原因是,包装器可以捕获插槽引发的异常(指示错误)并打印到控制台。

【问题讨论】:

    标签: pyqt signals-slots python-decorators pyqt5


    【解决方案1】:

    我突然想到问题是wrapper 函数没有正确的名称,无法被自动连接系统找到。所以下面解决了这个问题:

    from functools import wraps
    def auto_slot(func):
        @wraps(func)
        def wrapper(self):
            func(self)
        return pyqtSlot()(wrapper)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-13
      • 1970-01-01
      • 2015-02-22
      • 2023-04-03
      • 1970-01-01
      • 2017-09-08
      • 2014-10-19
      • 2021-01-20
      相关资源
      最近更新 更多