У меня есть приложение PyQt5, которое имеет дополнительные функциональные возможности (скажем, кнопку), которое отображается только тогда, когда приложению явно сказано «Включите эту опцию».Когда эта кнопка вызывается, приложение выполняет некоторое вычисление и затем выдает сигнал с результатом.
Вместо того, чтобы явно передавать опцию конструктора, я хотел бы, чтобы программа отображала функциональность, когда кто-то подключается кsignal.
Рабочий пример :
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()
Я не смог найти ни одной доступной опции в документации, и мне не удалось найти реализацию этой функции,В своем собственном коде я попытался напрямую изменить функцию соединения, но я получил AttributeError только для чтения.
Функция Wrapper :
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:
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.