Send an additional variable while pressing the PyQt PushButton button.

I am new to Python and PyQt, and this is my first application. Currently, pressing the toggleLED() button checks self.LedOn to decide whether to turn on the LED.

 class Screen(QWidget): def initUI(self): self.LedOn = 0 btn = QPushButton('Off', self) btn.setCheckable(True) btn.clicked.connect(self.toggleLED) def toggleLED(self, pressed): source = self.sender() if self.LedOn: source.setText('Off') source.LedOn = 0 self.serial.write('L') else: source.setText('On') source.LedOn = 1 self.serial.write('H') 

Problem: Now, if we want to control several LEDs and remember their individual switching state, what is the best practice?

I also cannot pass the extra toggleLED() value using btn.clicked.connect(self.toggleLED(btnNumber))

 class Screen(QWidget): def initUI(self): btn1 = QPushButton('Off', self) btn1.setCheckable(True) btn1.LedOn= 0 btn1.clicked.connect(selftoggleLED(1)) btn2 = QPushButton('Off', self) btn2.setCheckable(True) btn2.LedOn= 0 btn2.clicked.connect(selftoggleLED(2)) def toggleLED(self, pressed, value): source = self.sender() if self.LedOn: source.setText('Off') self.serial.write(value) self.serial.write('L') else: source.setText('On') self.serial.write(value) self.serial.write('H') 
+4
source share
5 answers

You can use partial for this:

 from functools import partial btn1.clicked.connect(partial(self.toggleLED, 1)) 

This allows you to pass multiple arguments to a function.

+7
source

Here is the solution that I always use for this job.

 class Screen(QWidget): def initUI(self): btn1 = QPushButton('Off', self) btn1.setCheckable(True) btn1.LedOn= 0 btn1.clicked.connect(selftoggleLED(1)) btn2 = QPushButton('Off', self) btn2.setCheckable(True) btn2.LedOn= 0 # I am adding these lines----------------------- # put all the btns in a list btns = [btn1, btn2] # connect each btn with the function and pass the same btn map(lambda btn: btn.clicked.connect(lambda pressed: self.toggleLED(pressed, btn)), btns) def toggleLED(self, pressed, clikedBtn): if pressed: clickedBtn.setText("On") # set other variables you need else: clickedBtn.setText("Off") # set other variables 
+1
source

To pass multiple arguments to a function, you can use either functools.partial() or lambda :

 btn2.clicked.connect(lambda: selftoggleLED(2)) 

Read a discussion of both methods .

+1
source

QPushButton already has a checked boolean property, so you don't need to create another. There are two signals from which the button is issued:

  • clicked on click
  • toggled when its state changes

Both pass a parameter indicating the state of the button. But I think the second is more suitable because of his name.

So, the toggleLED slot should look like this:

 def toggleLED(self, checked): source = self.sender() if checked: source.setText('Off') self.serial.write('L') else: source.setText('On') self.serial.write('H') 

Please note that only the tested buttons give a toggled signal, but you have already set this property in your code:

 def initUI(self): btn1 = QPushButton('Off', self) btn1.setCheckable(True) btn1.toggled.connect(self.toggleLED) btn2 = QPushButton('Off', self) btn2.setCheckable(True) btn2.toggled.connect(self.toggleLED) 
0
source
 class Screen(QWidget): def initUI(self): btn1 = QPushButton('Off', self) btn1.setCheckable(True) btn1.value = 1 btn1.clicked.connect(selftoggleLED) btn2 = QPushButton('Off', self) btn2.setCheckable(True) btn2.value = 2 btn2.clicked.connect(selftoggleLED) def toggleLED(self, pressed): source = self.sender() if pressed: source.setText('Off') self.serial.write(source.value) self.serial.write('L') else: source.setText('On') self.serial.write(source.value) self.serial.write('H') 
  • The tested QPushButton will keep state, so you do not need btn.LedOn .
  • Use btn.value to store the btn number, so you don't need to send an extra argument.
0
source

All Articles