我怎样才能正确装饰PyQt回调函数?

时间:2018-04-12 13:59:14

标签: python pyqt4 python-decorators

在python中PyQt信号的回调函数也有"隐藏"参数" state"。该参数通过用户定义的装饰器进行更难的功能装饰。

我的代码示例和装饰器。在我的解决方案中,我必须承认由错误的参数计数引起的TypeErrors,对于没有lambda的每个回调,其他我无法装饰。有没有更好的方法,我可以排除承认TypeError?我可以忽略"州"参与者在我的装饰者中以某种方式?

代码示例:装饰器和程序示例。

from PyQt4 import QtCore, QtGui

def decor(func_fuc):
    def new_func(*args, **kwargs):
        #do something
        try:
            func_fuc(*args, **kwargs)
        except TypeError as TypE:
            if all(i in TypE.args[0] for i in ['takes', 'positional', 'argument' ,'but', 'given']):
                args = tuple([args[ar] for ar in range(len(args)-1)])
                func_fuc(*args, **kwargs)
            else:
                raise TypE
        #etc
    return new_func

class MainWind(QtGui.QMainWindow):
    @decor
    def __init__(self,parent=None,geometry = QtCore.QRect(100,100,800,800)):
        super(MainWind, self).__init__(parent,geometry=geometry)
        self.pushik = QtGui.QPushButton(
            self, clicked = self.vasa
            ,geometry = QtCore.QRect(100,100,50,50), text = 'vasa'
        )

        self.petjaBtn = QtGui.QPushButton(
            self, clicked = lambda state : self.petja()
            ,geometry = QtCore.QRect(100,200,50,50), text = 'petja'

        )

        self.someBtn = QtGui.QPushButton(
            self, clicked = self.someBtnClick
            ,geometry = QtCore.QRect(100,300,50,50), text = 'someBtn'
        )

        self.show()
    #@decor
    def vasa(*args):
        print('vasa call')
        print(args) #(<__main__.MainWind object at 0x018FF940>, False)
    #@decor
    def petja(*args):
        print('petja call')
        print(args) #(<__main__.MainWind object at 0x018FF940>,)

    def someBtnClick(self): # usual usage
        print('someBtnClick call')
        # signature : accept only "self", but works fine on button click(with 2 params, self and state)
        # if i write empty decorator, that just returns original call, i will get typeError (reason - extra argument)
        #how to decorate without admitting "argument" TypeError?

app=QtGui.QApplication([])
wind = MainWind()
app.exec_()

1 个答案:

答案 0 :(得分:0)

如果您查看装饰功能的inspect.getfullargspec(),您会发现它们的签名是“ wong”。 参见Fix Your Decoratorswrapt library

但是不幸的是,尽管@wrapt.decorator()看起来很正确,但使用getfullargspec()编写装​​饰器仍不能解决问题。似乎PyQt还要进行一次代码检查以计算功能属性。