[英]Global signaling in Pyside6?
我想在我的主窗口中发出一个信号,并且在我想接收该信号的某个组件深处的某个地方发出信号。 我在这里读过一些可以用通用信号类解决的线程,但是我不能让它工作。
我创建了一个带有测试信号的信号管理器类:
class Manager(QObject):
test_signal = Signal(str)
def __init__(self):
QObject.__init__(self)
在我的主窗口中,我这样做:
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.signal_manager = SignalManager.Manager()
def some_button_clicked(self):
self.signal_manager.test_signal.emit('test')
在某个组件的深处:
class MyTreeWidget(QTreeWidget):
def __init__(self, parent=None):
QTreeWidget.__init__(self, parent)
self.signal_manager = SignalManager.Manager()
self.signal_manager.test_signal.connect(self.do_something)
def do_something(self, param):
# Do something...
所以当我点击我的按钮并且 some_button_clicked 发出事件 do_something() 应该发生但它不会发生。 想知道这里可能是什么问题?
您的解决方案不起作用,因为您总是在创建管理器的新实例。
每当我需要依赖 Qt 程序中的一些“全局”对象时,我通常会创建 QApplication 的子类并为它们创建属性,这显然也适用于“全局信号”。
然后您可以通过访问应用程序instance()
发出信号或连接到它们:
class MyApp(QApplication):
globalSignal = pyqtSignal(str)
class TargetLabel(QLabel):
def __init__(self):
super().__init__()
QApplication.instance().globalSignal.connect(self.setText)
app = MyApp([])
window = QWidget()
layout = QVBoxLayout(window)
lineEdit = QLineEdit()
layout.addWidget(lineEdit)
layout.addWidget(TargetLabel())
lineEdit.textChanged.connect(app.globalSignal)
window.show()
app.exec()
另一种方法是在单独的模块中使用全局 QObject 子类,使用对对应于唯一实例的模块的全局引用(使用global
实际上有意义的罕见情况之一)。
一个可能的“hacky”实现是创建一个名为信号管理器的函数,并将其全局引用替换为 QObject 的实例,如下例所示:
globalsignal.py
from PyQt5 import QtCore
def GlobalSignalProxy():
global GlobalSignalProxy
if not isinstance(GlobalSignalProxy, QtCore.QObject):
class GlobalSignalProxy(QtCore.QObject):
signal = QtCore.pyqtSignal(str)
# replace the function with the instance
GlobalSignalProxy = GlobalSignalProxy()
return GlobalSignalProxy
targetlabel.py
from PyQt5 import QtWidgets
from globalsignal import GlobalSignalProxy
class TargetLabel(QtWidgets.QLabel):
def __init__(self):
super().__init__()
GlobalSignalProxy().signal.connect(self.setText)
main.py
from PyQt5 import QtWidgets
from globalsignal import GlobalSignalProxy
from targetlabel import TargetLabel
app = QtWidgets.QApplication([])
window = QtWidgets.QWidget()
layout = QtWidgets.QVBoxLayout(window)
lineEdit = QtWidgets.QLineEdit()
layout.addWidget(lineEdit)
lineEdit.textChanged.connect(GlobalSignalProxy().signal)
layout.addWidget(TargetLabel())
window.show()
app.exec()
以上显然也可以通过单例类来实现。
无论如何,我不建议这种做法,因为我相信 QApplication 子类会更好,原因有很多,包括它更适合 OOP 模式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.