Reputation: 131
I have two couple classes(A, B, C, D), one of them is GUI class(A) which contains progressbar. So is it possible to send progress signals from B, C, D classes to A class ?
in pseudo-code it's something like:
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)
But maybe there's something better, that my messy approach ?
Upvotes: 2
Views: 4347
Reputation: 1713
As far as I see you have got the basic idea right. :) Few things could be improved upon.
Firstly, calling connect_and_send(...)
would cause the signal-slot-connection to be created each time you call the function. So it'll be better to create the connection elsewhere.
Secondly, you have used the new style signal-slots, good for you, but the connection is erroneous. You have the line self.progress.connect(self.gui.progressBar)
. This will cause the progressbar object itself to be called like this self.gui.progressBar()
and trigger a TypeError
:
Traceback (most recent call last):
File "...", line ..., in ...
TypeError: 'QProgressBar' object is not callable
Change self.progress.connect( self.gui.progressBar )
to self.progress.connect( self.gui.progressBar.setValue )
. This call will result in self.gui.progressBar.setValue( <some_integer_value> )
which is what you want.
So your final code could be changed to something like::
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> )
Take care to call the prepareGui()
function before calling some_function()
, otherwise, the connection will not have been made, and progress bar will not get updated.
[b]Edit:[/b] The more I think about this question, the more I feel that the classes should be reversed, in ideal case, unless you are calling the GUI from the command line, which is quite unlikely.
Since, B, C and D are non-gui, you may want to instantiate them in A like this:
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
...
...
This way the GUI is shown first. Then the non-gui elements start their work, and interact with the GUI to display the progress in the progressBar
Upvotes: 3