PyQt自动插槽:用包装器修饰时不调用

时间:2015-02-25 06:04:53

标签: pyqt signals-slots python-decorators pyqt5

我通过Qt Designer创建了QWidgetQPushButton名为fooQWidget的方法名为on_foo_clicked

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

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

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

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,则带有auto_slot的{​​{1}}装饰器按预期工作,并调用该方法点击按钮时。

如果wrapper auto_slot可以使用wrapper执行某些操作,以便即使使用自动连接的插槽也能正常工作?

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

1 个答案:

答案 0 :(得分:1)

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

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