繁体   English   中英

PyQt5 信号在两个 class 之间发射

[英]PyQt5 signal emit between two class

我只是想从 class A 向 class B 发送一个信号,但它不起作用,我看不到打印。 我当然做错了什么,但我确实知道是什么。 这是一个快速代码,可以向您展示问题,谢谢。

from PyQt5 import QtWidgets, QtCore
import sys


class B(object):
    def __init__(self, parent=None):
        super(B, self).__init__(parent)
        self._initSlot()

    def _initSlot(self):
        a = A()
        a.assetSelectionChanged.connect(self._doSomething)

    @QtCore.pyqtSlot()
    def _doSomething(self):
        print('do something')


class A(QtWidgets.QWidget):

    assetSelectionChanged = QtCore.pyqtSignal()

    def __init__(self, parent=None):
        super(A, self).__init__(parent)
        self._initUI()

    def _initUI(self):

        self.treeWidgetAssets = QtWidgets.QTreeWidget()
        for i in range(1, 11, 1):
            QtWidgets.QTreeWidgetItem(self.treeWidgetAssets, [str(i)])

        self.mainLayout = QtWidgets.QVBoxLayout()
        self.setLayout(self.mainLayout)
        self.mainLayout.addWidget(self.treeWidgetAssets)
        self.treeWidgetAssets.itemSelectionChanged.connect(self.onAssetSelectionChanged)

    def onAssetSelectionChanged(self):
        self.assetSelectionChanged.emit()


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    dlg = A()
    dlg.show()
    sys.exit(app.exec_())

该代码存在各种问题:

  • 没有创建B的实例
  • 直接object子类不需要调用super().__init__() ,即使你这样做了,你当然也不应该添加任意 arguments,因为它们不会被接受,导致崩溃
  • B应该继承自 QObject
  • 不应该在_initSlot中声明新实例:已经存在一个,并且您正在创建的实例将立即被垃圾收集,因为它的引用是本地的,并且将在_initSlot返回后立即删除
class B(QtCore.QObject):
    def __init__(self, parent=None):
        super(B, self).__init__(parent)
        self._initSlot()

    def _initSlot(self):
        if self.parent(): self.parent().assetSelectionChanged.connect(self._doSomething)

    @QtCore.pyqtSlot()
    def _doSomething(self):
        print('do something')


class A(QtWidgets.QWidget):

    assetSelectionChanged = QtCore.pyqtSignal()

    def __init__(self, parent=None):
        super(A, self).__init__(parent)
        self._initUI()
        self.b = B(self)

    # ...

作为变体。 我已经标记了我为你更改的行。

import sys
from PyQt5 import QtWidgets, QtCore


class B(QtCore.QObject):
    def __init__(self, parent=None):
        super(B, self).__init__(parent)
#        self._initSlot()
#    def _initSlot(self):
#        a = A()
#        a.assetSelectionChanged.connect(self._doSomething)

    @QtCore.pyqtSlot(str)
    def _doSomething(self, text):
        print(f'do something: clicked -> {text}')


class A(QtWidgets.QWidget):
    assetSelectionChanged = QtCore.pyqtSignal(str)                       # 1. + str 

    def __init__(self, parent=None):
        super(A, self).__init__(parent)
        
        self._initUI()
        
        self.b = B(self)                                                 # !!!
        self.assetSelectionChanged[str].connect(self.b._doSomething)     # 3. + str 

    def _initUI(self):
        self.treeWidgetAssets = QtWidgets.QTreeWidget()
        for i in range(1, 11, 1):
            QtWidgets.QTreeWidgetItem(self.treeWidgetAssets, [str(i)])

        self.mainLayout = QtWidgets.QVBoxLayout()
        self.setLayout(self.mainLayout)
        self.mainLayout.addWidget(self.treeWidgetAssets)
        self.treeWidgetAssets.itemSelectionChanged.connect(self.onAssetSelectionChanged)

    def onAssetSelectionChanged(self):
        text = self.treeWidgetAssets.selectedItems()[0].text(0)
        self.assetSelectionChanged.emit(text)                            # 2. + text 


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    dlg = A()
    dlg.show()
    sys.exit(app.exec_())

在此处输入图像描述

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM