PyQt5在类之间发送信号?

时间:2016-07-09 13:57:37

标签: signals pyqt5

我有两个类(A,B,C,D),其中一个是包含进度条的GUI类(A)。 那么可以将B,C,D类的进度信号发送给A类吗?

伪代码中的

就像:

from a import A
from PyQt5.Core import pyqtSignal

 class B(QObject):
     ...
     self.gui = A()
     progress = pyqtSignal(int)

     def connect_and_send(self, value):
         self.progress.connect(self.gui.progressBar)
         self.progress.emit(value)

但也许有更好的东西,我的凌乱方法?

1 个答案:

答案 0 :(得分:0)

据我所知,你的基本想法是正确的。 :)很少有东西可以改进。

首先,调用connect_and_send(...)会导致每次调用函数时都会创建信号槽连接。因此,在其他地方创建连接会更好。

其次,您使用了新型信号槽,对您有好处,但连接错误。你有一行self.progress.connect(self.gui.progressBar)。这将导致进度条对象本身像self.gui.progressBar()一样被调用并触发TypeError

Traceback (most recent call last):
  File "...", line ..., in ...
TypeError: 'QProgressBar' object is not callable

self.progress.connect( self.gui.progressBar )更改为self.progress.connect( self.gui.progressBar.setValue )。此调用将导致self.gui.progressBar.setValue( <some_integer_value> )这是您想要的。

所以你的最终代码可以改为::

from a import A
from PyQt5.Core import pyqtSignal

class B( QObject ) :
    ...
    progress = pyqtSignal(int)
    ...

    def prepareGui( self ) :
        self.gui = A()
        self.gui.progressBar.setRange( 0, 100 )
        self.progress.connect( self.gui.progressBar.setValue )

        # You'll want to show the GUI
        self.gui.show()       

    def some_function( self ) :
        ...
        ...
        ...

        self.progress.emit( <some_number> )

在致电prepareGui()之前,请务必致电some_function(),否则,系统将无法建立连接,并且不会更新进度条。

并[b]编辑:[/ B] 我对这个问题的思考越多,在理想的情况下,我觉得这些类应该被颠倒过来,除非你从命令行调用GUI,这是不太可能的。

因为,B,C和D都是非gui,你可能想要在A中实例化它们:

class B(QObject):
    progress = pyqtSignal( int )

    # Other class constructs/functions/members
    ...
    ...

class A( QMainWindow ) :
    """Qt Application Details
    """

    def __init__( self ) :
        """Class initialiser
        """

        ...

        self.createGUI()
        self.setupBCD()

    def createGUI( self ) :

        # Create you progress bars and other gui
        ...
        ...

        self.progressBar = QProgressBar( self )
        self.progressBar.setRange( ... )

    def setupBCD( self ) :

        # Setup classes B, C and D
        self.classB = B()
        self.classB.progress.connect( self.progressBar.setValue )

        # Similar connection for others
        ...
        ...

这样首先显示GUI。然后非gui元素开始工作,并与GUI交互以显示progressBar

中的进度