簡體   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