pyqt 当槽函数被装饰器修饰时按钮的clicked信号总是会自动传入bool值参数的解决方案

  • 最近在做pyqt的项目,有一个地方是按钮的clicked信号触发一个被装饰器修饰的槽函数,然而点击按钮却报错多传了参数func takes 1 positional argument but 2 were given
  • 在槽函数里用*args接一下这个多的参数,打印出来是个bool值False
  • 百度一番,发现按钮的点击事件有clickedclicked[bool]两个信号。这两个信号一个不传参,一个传一个bool参数,当槽函数接受额外参数时,会自动使用clicked[bool]信号,否则使用clicked,也就是说,只要槽函数需要接收参数,clicked信号就会传入bool参数。
  • 但是,我的槽函数没有接收额外参数呀,为什么会传参呢?因为使用了装饰器!
  • 我的装饰器定义时使用了如下形式
def my_decorator(func):
    def wrapper(self,*args,**kwargs):
        # do something
        return func(self,*args,**kwargs)
    retrun wrapper
    
class Demo:
    def __init__(self):
        # bind the signal and function
        ...
        self.ui.pushButton_disconnect.clicked.connect(
            self.robot.disconnect_devices
        )
        ...
    # function
    @my_decorator
    def disconnect_devices(self, *args):
        print(args)
        # do something
  • 也就是说我的装饰器可以接收额外参数,所以clicked信号直接多传进来一个参数。可不可以禁止clicked信号传参呢?很遗憾,不可以!
  • 要想解决这个问题就只能让槽函数接收这个额外参数(使用*args)或者修改一下装饰器,让装饰器不接收这个多余的参数。
  • 最简单的方法:装饰器不使用*args**kwargs,但是我的装饰器确实需要修饰一些其他带参的函数,所以行不通。或者直接为出问题的函数单独写一个装饰器。
  • 复杂一点的方法:装饰器检查被装饰函数的参数个数,只把对应个数的参数传进去,把多余的参数都扔掉。
import inspect
...
def my_decorator(func):
    if len(inspect.signature(func).parameters) == 1:
        original_func = func
        func = lambda self, *_: original_func(self)
    def wrapper(self, *args, **kwargs):
        return func(self, *args, **kwargs)
    return wrapper

class Demo:
    ...
    @my_decorator
    def disconnect_devices(self):
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值