I am trying to learn PyQt
from rapid gui programming with python and qt
and currently learning Signals
and Slots
.
Below is a short snippet of my code:
self.connect(self.dial, SIGNAL("valueChanged(int)"),self.spinbox.setValue) #1
self.connect(self.dial, SIGNAL("valueChanged(int)"),self.getValue_dial) #2
self.connect(self.spinbox, SIGNAL("valueChanged(int)"),self.dial.setValue)
self.connect(self.spinbox, SIGNAL("valueChanged(int)"),self.getValue_spinbox)
def getValue_dial(self):
print self.dial.value()
def getValue_spinbox(self):
print self.dial.value()
What I am trying to achieve here is call 2
SLOTS at once that is spinbox.setValue
and getValue_dial
for dial
object as soon as ValueChanged(int)
signal is emitted.
The above code executes successfully without any errors and print
the appropriate values as they are changed.
Now my question is the above way appropriate to call multiple slots for a single signal.?
Can the above two statements(1 & 2) be combined into a single statement.
Here is the link for my complete code.
You can connect as many signals as you want to a single slot, and a signal can be connected to as many slots as you need. It is even possible to connect a signal directly to another signal. (This will emit the second signal immediately whenever the first is emitted.)
You can have as many signals you want connected to one slot and vice versa. If several slots are connected to one signal, the slots will be executed one after the other, in the order they have been connected, when the signal is emitted.
To connect the signal to the slot, we use QObject::connect(). There are several ways to connect signal and slots. The first is to use function pointers: connect(sender, &QObject::destroyed, this, &MyObject::objectDestroyed);
Each PyQt widget, which is derived from QObject class, is designed to emit 'signal' in response to one or more events. The signal on its own does not perform any action. Instead, it is 'connected' to a 'slot'. The slot can be any callable Python function.
The way you're doing it is fine. If you had quite a few things to do you could connect to a new function that handles everything for you.
I notice in your connected getValue
functions you're getting the value straight from the object; are you aware that the value is passed as a parameter with the valueChanged(int)
signal? If you change your getValue
functions to accept an additional parameter there will be no need to get the value directly from the object. Of course you could do away with the getValue
function all together and issue your print statement in the helper function.
self.connect(self.dial, SIGNAL("valueChanged(int)"), self.dial_value_changed)
self.connect(self.spinbox, SIGNAL("valueChanged(int)"),self.spinbox_value_changed)
def dial_value_changed(self, value):
self.spinbox.setValue(value)
self.getValue_dial(value)
def spinbox_value_changed(self, value):
self.dial.setValue(value)
self.getValue_spinbox(value)
def getValue_dial(self, value):
print value
def getValue_spinbox(self, value):
print value
Also, and this is down to preference, there is a new style for signals and slots which can make the code a little easier to read. It would change the
self.connect(self.dial, SIGNAL("valueChanged(int)"), self.dial_value_changed)
self.connect(self.spinbox, SIGNAL("valueChanged(int)"),self.spinbox_value_changed)
lines above to
self.dial.valueChanged.connect(self.dial_value_changed)
self.spinbox.valueChanged.connect(self.spinbox_value_changed)
But for the original question and for the two things you're doing I'd just connect the signal twice rather than have a helper function.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With