英文:
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):
...
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论