我想在我的主窗口发出一个信号,在我的一个部件的深处,我想要接收到这个信号。我在这里读过一些可以用普通信号类解决的线程,但是我无法使它工作。
我创建了一个信号管理器类,其中包含一个测试信号:
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()应该会发生,但它不会发生。
发布于 2022-07-21 23:58:59
您的解决方案不起作用,因为您总是在创建管理器的一个新实例。
每当我需要依赖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 GlobalSignalProxytargetlabel.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模式这一事实。
https://stackoverflow.com/questions/73073370
复制相似问题