【问题标题】:Python PyQt Decorated Method Errors when Triggered触发时 Python PyQt 装饰方法错误
【发布时间】:2012-06-13 21:55:06
【问题描述】:

我过去使用过装饰器没有任何问题,但我坚持使用这个。似乎当我的装饰函数被 PyQt 操作调用时,它失败了。我的理论是 PyQt 以某种方式在内部包装了连接的函数并弄乱了签名或类似的东西,但我找不到任何证据。

连接我的意思是这样的:

from PyQt4 import QtGui

# In my widget init...
self.action_my_method = QtGui.QAction("action_my_method", self)
self.action_my_method.triggered.connect(self.my_method)

这是我的简单装饰器:

from functools import wraps

def simple_decorator(fn):
    @wraps(fn)
    def wrapper(*args, **kwargs):
        from inspect import getargspec
        print getargspec(fn)

        return fn(*args, **kwargs)
    return wrapper

当我使用它来装饰一个没有任何参数的方法 (def my_method(self)),并直接从我的 QWidget 类中执行它时,它工作正常。当我使用菜单触发动作时,我得到:

# Traceback (most recent call last):
#   File "[...].py", line 88, in wrapper
#     return fn(*args, **kwargs)
# TypeError: my_method() takes exactly 1 argument (2 given)

我看到了一个 arg 规范:

ArgSpec(args=['self'], varargs=None, keywords=None, defaults=None)

如果我将*args 添加到我的方法中,则签名为my_method(self, *args),则装饰器工作正常且arg 规范为:

ArgSpec(args=['self'], varargs='args', keywords=None, defaults=None)

我在这里看不到任何线索,因为装饰器在直接调用时工作正常,但在被操作触发时会失败。

任何人都可以对此有所了解,或者提供一些我可以用来进一步调试它的东西吗?

【问题讨论】:

    标签: python qt pyqt action decorator


    【解决方案1】:

    这与其说是一种解决方法,不如说是一种解决方法。我希望这没有任何不利之处。我在输入一个简单的重定向功能时想到了它。这使用 lambda 在运行时做同样的事情:

    self.action_my_method.triggered.connect(lambda: self.my_method())
    

    这足以防止我的装饰函数被破坏并防止错误。

    【讨论】:

      【解决方案2】:

      或者,您可以将可能通过 .connect 调用的每个方法的签名重新定义为:

      def my_method(self, qtcallparam=None, **kwargs):
      

      因此该方法将忽略第一个未命名的参数,代价是在该方法中使用严格的关键字参数(这不是一件坏事)

      但@Rafe 的解决方案可能更干净

      【讨论】:

        猜你喜欢
        • 2013-06-08
        • 1970-01-01
        • 1970-01-01
        • 2015-12-10
        • 2010-10-16
        • 1970-01-01
        • 2013-06-23
        • 2012-02-09
        • 2018-01-28
        相关资源
        最近更新 更多