I'm trying to create buttons (QPushButtons) based on an entry (QLineEdit). The idea is that I want the user to be able to create as many buttons as wanted, simply by adding new text in the entry box and by then pressing "Add Label" (see picture below).
While I'm able to do this, I can't for now retrieve the label value of each of these buttons, since the procedure I use erases all the previous values (I can only retrieve the last value entered). I'd like to be able to print each specific Label Value when clicking each button.
My code is below:
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QLineEdit
import sys
class MyWindow(QMainWindow):
def __init__(self):
super(MyWindow, self).__init__()
self.setGeometry(100, 100, 1500, 1500)
self.setWindowTitle("My Program")
self.labelButtons = [] # List of all the buttons displaying labels
self.eraseButtons = [] # List of all the buttons displaying "X"
self.Yposition = 50
self.initUI()
def initUI(self):
self.labelEntry = QLineEdit(self)
self.labelEntry.move(50, self.Yposition)
self.labelEntry.resize(300, 40)
self.addLabelButton = QPushButton(self)
self.addLabelButton.setText("Add Label")
self.addLabelButton.move(400, self.Yposition)
self.addLabelButton.resize(300, 40)
self.addLabelButton.clicked.connect(self.addNewLabel)
def addNewLabel(self):
self.Yposition += 50
self.newLabelName = self.labelEntry.text()
self.labelButtons.append(self.createButtonLabel(self.newLabelName))
self.eraseButtons.append(self.eraseButtonLabel())
self.updatelabels()
def createButtonLabel(self, labelname):
self.button = QPushButton(self)
self.button.setText(str(labelname))
self.button.resize(300, 40)
self.button.move(50, self.Yposition)
self.button.clicked.connect(self.printbutton)
return self.button
def eraseButtonLabel(self):
self.buttonErase = QPushButton(self)
self.buttonErase.setText("X")
self.buttonErase.resize(40, 40)
self.buttonErase.move(360, self.Yposition)
self.buttonErase.clicked.connect(self.printbutton)
return self.buttonErase
def updatelabels(self):
for button in self.labelButtons:
button.show()
for button in self.eraseButtons:
button.show()
def printbutton(self):
print(self.button.text())
if __name__ == '__main__':
app = QApplication(sys.argv)
win = MyWindow()
win.show()
sys.exit(app.exec_())
<!-- end snippet -->
Using Google pyqt clicked event
I found you have to use
def printbutton(self):
widget = self.sender()
print(widget.text())
ZetCode: Events and signals in PyQt5
EDIT:
As for erease
button - you should get button from createButtonLabel
and send it to eraseButtonLabel
labelbutton = self.createButtonLabel(self.newLabelName)
erasebutton = self.eraseButtonLabel(labelbutton)
and you can use lambda
to assing function with argument
def eraseButtonLabel(self, labelbutton):
# ... code ...
self.buttonErase.clicked.connect(lambda: self.erasebutton(labelbutton))
and function should get this argument
def erasebutton(self, button):
widget = self.sender()
print('clicked:', widget.text())
print(' erase:', button.text())
Or you can assing button
to own variable in buttonErase
def eraseButtonLabel(self, labelbutton):
# ... code ...
self.buttonErase.assigned_button = labelbutton
self.buttonErase.clicked.connect(self.erasebutton)
and use it in function
def erasebutton(self):
widget = self.sender()
print('clicked:', widget.text())
print(' erase:', widget.assigned_button.text())
Full code which uses both methods at the same time but you need only one method.
from PyQt5.QtWidgets import *
import sys
class MyWindow(QMainWindow):
def __init__(self):
super(MyWindow, self).__init__()
self.setGeometry(100, 100, 1500, 1500)
self.setWindowTitle("My Program")
self.labelButtons = [] # List of all the buttons displaying labels
self.eraseButtons = [] # List of all the buttons displaying "X"
self.Yposition = 50
self.initUI()
def initUI(self):
self.labelEntry = QLineEdit(self)
self.labelEntry.move(50, self.Yposition)
self.labelEntry.resize(300, 40)
self.addLabelButton = QPushButton(self)
self.addLabelButton.setText("Add Label")
self.addLabelButton.move(400, self.Yposition)
self.addLabelButton.resize(300, 40)
self.addLabelButton.clicked.connect(self.addNewLabel)
def addNewLabel(self):
self.Yposition += 50
self.newLabelName = self.labelEntry.text()
labelbutton = self.createButtonLabel(self.newLabelName)
erasebutton = self.eraseButtonLabel(labelbutton)
self.labelButtons.append(labelbutton)
self.eraseButtons.append(erasebutton)
self.updatelabels()
def createButtonLabel(self, labelname):
self.button = QPushButton(self)
self.button.setText(str(labelname))
self.button.resize(300, 40)
self.button.move(50, self.Yposition)
self.button.clicked.connect(self.printbutton)
return self.button
def eraseButtonLabel(self, labelbutton):
self.buttonErase = QPushButton(self)
self.buttonErase.setText("X")
self.buttonErase.resize(40, 40)
self.buttonErase.move(360, self.Yposition)
self.buttonErase.assigned_button = labelbutton
self.buttonErase.clicked.connect(lambda: self.erasebutton(labelbutton))
#self.buttonErase.clicked.connect(self.erasebutton)
return self.buttonErase
def updatelabels(self):
for button in self.labelButtons:
button.show()
for button in self.eraseButtons:
button.show()
def printbutton(self):
print('clicked:', self.sender().text())
def erasebutton(self, button):
widget = self.sender()
print('clicked:', widget.text())
print(' erase:', button.text())
print(' erase:', widget.assigned_button.text())
if __name__ == '__main__':
app = QApplication(sys.argv)
win = MyWindow()
win.show()
sys.exit(app.exec_())
EDIT:
Other method is to create own widget which has both buttons labelbutton
and erasebutton
and then erasebutton
has direct access only to own labelbutton
.
BTW: and for similar reason I would keep buttons as pairs
self.buttons.append([labelbutton, erasebutton])
instead of separted lists
self.labelButtons.append(labelbutton)
self.eraseButtons.append(erasebutton)
Example in which I create own widget.
from PyQt5.QtWidgets import *
import sys
class MyWidget(QWidget):
def __init__(self, parent, labelname, *args, **kwargs):
super().__init__(parent, *args, **kwargs)
self.resize(350, 40)
self.labelButton = QPushButton(self)
self.labelButton.setText(str(labelname))
self.labelButton.resize(300, 40)
self.labelButton.move(0, 0)
self.labelButton.clicked.connect(self.printbutton)
self.buttonErase = QPushButton(self)
self.buttonErase.setText("X")
self.buttonErase.resize(40, 40)
self.buttonErase.move(310, 0)
self.buttonErase.clicked.connect(self.erasebutton)
self.show()
def printbutton(self):
print('clicked:', self.labelButton.text())
def erasebutton(self):
print('clicked:', self.buttonErase.text())
print(' erase:', self.labelButton.text())
class MyWindow(QMainWindow):
def __init__(self):
super(MyWindow, self).__init__()
self.setGeometry(100, 100, 1500, 1500)
self.setWindowTitle("My Program")
self.widgets = []
self.Yposition = 50
self.initUI()
def initUI(self):
self.labelEntry = QLineEdit(self)
self.labelEntry.move(50, self.Yposition)
self.labelEntry.resize(300, 40)
self.addLabelButton = QPushButton(self)
self.addLabelButton.setText("Add Label")
self.addLabelButton.move(400, self.Yposition)
self.addLabelButton.resize(300, 40)
self.addLabelButton.clicked.connect(self.addNewLabel)
def addNewLabel(self):
self.Yposition += 50
text = self.labelEntry.text()
widget = MyWidget(self, text)
widget.move(50, self.Yposition)
self.widgets.append(widget)
if __name__ == '__main__':
app = QApplication(sys.argv)
win = MyWindow()
win.show()
sys.exit(app.exec_())