0

I am new to pyqt (pyside in maya), please be nice to me :)

so the point is i want to generate many button via loop statement, something simmilar like below :

(5 button in a window - complete code - maya)

import PySide.QtCore as qc
import PySide.QtGui as qg
class simpleUI(qg.QDialog):
    def __init__(self):
        qg.QDialog.__init__(self)
        self.setWindowTitle('Simple UI')
        self.btn=[]
        for x in range(5) :
           self.btn.append(x)
           self.btn[x]= qg.QPushButton(self)
           self.btn[x].setText('this is btn number{0}'.format(x))
           self.btn[x].setGeometry(qc.QRect(0,100+(x*20), 100,20))
           self.btn[x].clicked.connect(lambda : self.notifyMe(x))
    def notifyMe(self,index):
        print index
dialog = simpleUI()
dialog.show()

as you see, I store button object in array, but the problem is when i want to connect btn signal with notifyMe function, every button always give x same value (x=4) , meanwhile in button.setText x succeed give unique incremental value, i can't figure it why..

Edit:

revisit this again after 6 years later, I wanna inform that I was always using partial rather than lambda, here is what I did on PySide2 / PyQt5:

import sys
from PySide2.QtWidgets import *
from functools import partial

class simpleUI:
    def __init__(self):
        app = QApplication()
        window = QMainWindow()
        layout = QVBoxLayout()

        for x in range(5):
            btn = QPushButton('this is btn number {0}'.format(x))
            btn.clicked.connect(partial(self.notifyMe, index=x))
            layout.addWidget(btn)
        widget = QWidget()
        widget.setLayout(layout)
        window.setCentralWidget(widget)
        #
        window.show()
        sys.exit(app.exec_())

    def notifyMe(self, index):
        print(index)

if __name__ == '__main__':
    simpleUI()
0

1 Answer 1

6

It is old problem with function in lambda - it doesn't get value from x when you declare function but when you click button. But when you click button then for-loop is over and x keeps last value - and this way all buttons use the same value. You have to use

lambda a=x: self.notifyMe(a)
Sign up to request clarification or add additional context in comments.

7 Comments

thanks furas, you explained perfectly !
I had to change it to also include the checked argument, that clicked() passes. eg. lambda checked, a=x: self.notifyMe(a), as per comment in question stackoverflow.com/questions/51522883/…
@Swedgin it is very old question and code uses PySide which (as I remeber) was using PyQt4 and it could work differently than in PyQt5
I only mention it for future visitors. I'm using PyQt5 atm.
@Swedgin page not found, i'm looking for solution for pyqt5
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.