gpt4 book ai didi

python - 监听 pyqtBoundSignal 上的新信号连接

转载 作者:行者123 更新时间:2023-11-30 21:56:12 24 4
gpt4 key购买 nike

我有一个 PyQt5 应用程序,它具有可选功能(假设有一个按钮),仅当应用程序被明确告知“打开此选项”时才会显示。调用此按钮时,应用程序会进行一些计算,然后发出包含结果的信号。

我希望程序在有人连接到信号时显示功能,而不是必须显式传递构造函数选项。

工作示例:

class ExampleApp(QWidget):
do_something = pyqtSignal(str)

def __init__(self, something_enabled: bool = False):
super().__init__()

self.button = QPushButton("Do something")
self.button.pressed.connect(self.do_work)

self.button.setVisible(something_enabled)

self.setLayout(QVBoxLayout())
self.layout().addWidget(self.button)

self.show()

def do_work(self):
self.do_something.emit("Something!")

if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
window = ExampleApp(something_enabled=True)
window.do_something.connect(lambda result: print(result))
app.exec()

我在文档中找不到任何可用的选项,也无法找到此功能的实现。在我自己的代码中,我尝试直接更改 connect 函数,但出现只读 AttributeError。

包装函数:

self.original_connect = self.do_something.connect

def new_connect(slot, type=None, no_receiver_check=False):
print("New connection!")
self.original_connect(slot, type, no_receiver_check)

self.do_something.connect = new_connect

属性错误:

AttributeError: 'PyQt5.QtCore.pyqtBoundSignal' object attribute 'connect' is read-only

我还创建了一个工作包装类,但我对未知的后果保持警惕。

包装类:

class SignalWrapper(QObject):

new_connection = pyqtSignal(object)

def __init__(self, signal_to_wrap):
super().__init__()
self.wrapped_signal = signal_to_wrap
self.signal = self.wrapped_signal.signal

def connect(self, slot, type=None, no_receiver_check=False):
self.new_connection.emit(slot)
return self.wrapped_signal.connect(slot)

def disconnect(self, slot=None): # real signature unknown; restored from __doc__
return self.wrapped_signal.disconnect(slot)

def emit(self, *args): # real signature unknown; restored from __doc__
return self.wrapped_signal.emit(*args)

def __call__(self, *args, **kwargs): # real signature unknown
return self.wrapped_signal.__call__(*args, **kwargs)

def __getitem__(self, *args, **kwargs): # real signature unknown
return self.wrapped_signal.__getitem__(*args, **kwargs)

def __repr__(self, *args, **kwargs): # real signature unknown
return self.wrapped_signal.__repr__(*args, **kwargs)

ExampleApp 的修改部分:

class ExampleApp(QWidget):
do_something = pyqtSignal(str)

def __init__(self):
super().__init__()
self.do_something = SignalWrapper(self.do_something)

我想知道是否有一种优雅的方式来拦截 PyQt 中的信号连接。

最佳答案

您不应更改内置函数的默认行为。由于隐藏的逻辑,这将使您的代码难以理解和维护(为什么信号会使按钮可见?)。

但是,您可以将连接包装在一个方法中:

class ExampleApp(QWidget):
def turnOnOption(self, callback):
"""
Make button visible. Callback will be called when the work is done.
"""
self.do_something.connect(callback)
self.button.setVisible(True)

window = ExampleApp()
#window.do_something.connect(lambda result: print(result))
window.turnOnOption(lambda result: print(result))

这对于其他开发人员来说是明确的,并且您的代码看起来不像黑魔法......

关于python - 监听 pyqtBoundSignal 上的新信号连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55543713/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com