I try to create a UI using PyQt5 where a user can create and delete labels, each label being a button (QPushButton) created following a text entry (QLineEdit), and each of these label buttons being accompanied by an associated X-button, which delete the label when clicked.
For this I have created a first QWidget class to create and display the main Widgets (the entry box, the Add Label button, and the overall layout).
I have then created a second QWidget class to generate each label button and its associated X button. Such elements are generated when user click the "Add Label" button of the first QWidget class.
My problem is that I now can't find how to properly display such generated label and X button. Nothing appears when I click the Add Label button, while the function to generate the label and X buttons is properly called (I checked with print).
GUI unable to display the label and X buttons:
Here is the code:
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QLineEdit, QWidget, QVBoxLayout, QHBoxLayout, QGridLayout, QGroupBox
import sys
class MyWindow(QMainWindow):
def __init__(self):
super(MyWindow, self).__init__()
self.setWindowTitle("My Program")
self.setGeometry(100, 100, 1500, 1500)
self.initUI()
def initUI(self):
widgets = MainWidgets()
self.setCentralWidget(widgets)
class MainWidgets(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.grid = QGridLayout()
self.grid.setColumnStretch(0, 1)
self.grid.setColumnStretch(1, 1)
self.grid.setColumnStretch(2, 1)
self.grid.setColumnStretch(3, 1)
self.labelEntry = QLineEdit(self)
self.addLabelButton = QPushButton(self)
self.addLabelButton.setText("Add Label")
self.addLabelButton.clicked.connect(self.addNewLabel)
self.hbox_labelAdd = QVBoxLayout()
self.hbox_labelAdd.addWidget(self.labelEntry)
self.hbox_labelAdd.addWidget(self.addLabelButton)
self.vbox1 = QVBoxLayout()
self.vbox1.addLayout(self.hbox_labelAdd)
self.vbox2 = QVBoxLayout()
self.vbox2.addStretch(1)
self.vbox_right = QVBoxLayout()
self.vbox_right.addLayout(self.vbox1)
self.vbox_right.addLayout(self.vbox2)
self.groupBox = QGroupBox("Labelling")
self.groupBox.setLayout(self.vbox_right)
self.grid.addWidget(self.groupBox, 0, 3)
self.setLayout(self.grid)
def addNewLabel(self):
labelname = self.labelEntry.text()
newLabelItems = Labels(self, labelname)
self.vbox1.addWidget(newLabelItems)
class Labels(QWidget):
def __init__(self, parent, labelname, *args, **kwargs):
super().__init__(parent, *args, **kwargs)
self.mylabelname = labelname
self.initUI()
def initUI(self):
self.labelButton = QPushButton(self)
self.labelButton.setText(str(self.mylabelname))
self.labelButton.clicked.connect(self.printbutton)
self.buttonErase = QPushButton(self)
self.buttonErase.setText("X")
self.buttonErase.clicked.connect(self.erasebutton)
def printbutton(self):
print('clicked:', self.labelButton.text())
def erasebutton(self):
self.labelButton.deleteLater()
self.buttonErase.deleteLater()
if __name__ == '__main__':
app = QApplication(sys.argv)
# app.setStyle('Fusion')
window = MyWindow()
window.show()
sys.exit(app.exec_())
I found a trick by creating an empty QPushButton and associating it to the label and X buttons in a layout, which allows to display the label and X button, but this is not a long-term solution, plus I can't find a way to display these label and X buttons full width in the layout, there get restricted to half the layout (whether I use grid, Vbox, or Hbox layout) for some reason I can't explain.
Here is the trick code (replace the def addNewLabel (self) function in the previous code):
def addNewLabel(self):
labelname = self.labelEntry.text()
newLabelItems = Labels(self, labelname)
fake_widget = QPushButton(self)
labelitems_lay = QHBoxLayout()
labelitems_lay.addWidget(fake_widget)
labelitems_lay.addWidget(newLabelItems)
self.vbox1.addLayout(labelitems_lay)
In the below picture you can see what it looks like with this trick:
GUI with the trick - zoomed on the area of interest:
The overall goal is to be able to generate buttons in a quite similar way as in this picture:
Scheme representing the desired output:
I think the issue I have is related to to layout, because thank to @furas yesterday I was able to achieve this goal but using the move() function to display buttons. Now that I'm trying to organise my UI with layouts, I unfortunately can't achieve it anymore.