如何防止PyQt按钮的点击信号在槽函数有装饰器时发送布尔值?

huangapple go评论66阅读模式
英文:

How to prevent the pyqt button's clicked signal from sending Boolean value when slot functions have a decorator?

问题

我正在使用Qt Designer和PyQt5构建一个QT项目。我有一个按钮,它发送一个带有布尔值的信号。

绑定信号和函数的代码如下(我的装饰器在类内部,但装饰器不应该是问题,因为不管使用哪个装饰器,单击信号都会传递布尔参数):

class Demo:
    def __init__(self):
        # 绑定信号和函数
        ...
        self.ui.pushButton_disconnect.clicked.connect(
            self.robot.disconnect_devices
        )
        ...
    
    def my_decorator(func):
        def wrapper(self, *args, **kwargs):
            # args和kwargs是必需的,因为其他装饰的函数有参数
            # 做一些操作
            return func(self, *args, **kwargs)
        return wrapper
    
    # 函数
    @my_decorator
    def disconnect_devices(self, *args):
        print(args)
        # 做一些操作

现在我必须使用*args来接收False。我知道在connect中使用lambda也可以避免这个问题。

我已经找到了原因:我正在使用装饰器装饰函数disconnect_devices,似乎点击信号会自动传递参数,因为装饰器中使用了*args,所以我必须在我的函数中使用*args。有没有办法避免这个问题?或者我是否可以将clicked信号修复为不带参数的信号?

英文:

I am building a QT project with qt designer and pyqt5. I have one button that sends a signal with a boolean value.
My code to bind the signal and function(my decorator is inside the class, but it shouldn't be a problem with my decorator, because no matter what decorator is used, the clicked signal will pass in the bool parameter):

class Demo:
    def __init__(self):
        # bind the signal and function
        ...
        self.ui.pushButton_disconnect.clicked.connect(
            self.robot.disconnect_devices
        )
        ...
    def my_decorator(func):
        def wrapper(self,*args,**kwargs):
            '''
            args and kwargs is necessary 
            because other decorated functions have parameters
            '''
            # do something
            return func(self,*args,**kwargs)
        retrun wrapper
    # function
    @my_decorator
    def disconnect_devices(self, *args):
        print(args)
        # do something

Now I have to use *args to receive False. I know that using lambda in connect can also avoid this issue.
I have found the reason: I am using a decorator to decorate the function disconnect_devices, it seems that clicked signal will automatically pass in parameters because *args is used in the decorator, so I have to use *args to in my function. Is there a way to avoid this? Or can I fix the clicked signal as a signal without parameters?

答案1

得分: 1

你不能修改QAbstractButton::clicked信号的签名。

相反,你可以创建一个新的装饰器来包装原始的装饰器,像这样。

...
def my_decorator(func):
    def wrapper(self, *args, **kwargs):
        return func(self, *args, **kwargs)
    return wrapper

def my_decorator_ignoring_args(func):
    return my_decorator(lambda self, *_: func(self))

class Demo:
    ...
    @my_decorator_ignoring_args
    def disconnect_devices(self):
        ...
...

另外,你可以只定义一个装饰器,如果被装饰的函数没有参数,就包装它,像这样。

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):
        ...
英文:

You can't modify the signature of the QAbstractButton::clicked signal.

Instead, you can create a new decorator wrapping the original decorator like this.

...
def my_decorator(func):
    def wrapper(self, *args, **kwargs):
        return func(self, *args, **kwargs)
    return wrapper

def my_decorator_ignoring_args(func):
    return my_decorator(lambda self, *_: func(self))

class Demo:
    ...
    @my_decorator_ignoring_args
    def disconnect_devices(self):
        ...
...

Also, you can define only single decorator and wrap the decorated function if it has no parameters, like this.

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):
        ...

huangapple
  • 本文由 发表于 2023年6月26日 16:52:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/76555070.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定