首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Pyside6中的全球信令?

Pyside6中的全球信令?
EN

Stack Overflow用户
提问于 2022-07-21 22:36:20
回答 1查看 134关注 0票数 1

我想在我的主窗口发出一个信号,在我的一个部件的深处,我想要接收到这个信号。我在这里读过一些可以用普通信号类解决的线程,但是我无法使它工作。

我创建了一个信号管理器类,其中包含一个测试信号:

代码语言:javascript
复制
class Manager(QObject):
  test_signal = Signal(str)
  def __init__(self):
    QObject.__init__(self)

在我的主窗口,我这样做:

代码语言:javascript
复制
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')

在其中一个组件的深处:

代码语言:javascript
复制
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()应该会发生,但它不会发生。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-07-21 23:58:59

您的解决方案不起作用,因为您总是在创建管理器的一个新实例。

每当我需要依赖Qt程序中的一些“全局”对象时,我通常会创建QApplication的一个子类并为它们创建属性,这显然也适用于“全局信号”。

然后,您可以通过访问应用程序instance()发出信号或连接到它们。

代码语言:javascript
复制
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

代码语言:javascript
复制
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

代码语言:javascript
复制
from PyQt5 import QtWidgets
from globalsignal import GlobalSignalProxy

class TargetLabel(QtWidgets.QLabel):
    def __init__(self):
        super().__init__()
        GlobalSignalProxy().signal.connect(self.setText)

main.py

代码语言:javascript
复制
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模式这一事实。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73073370

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档