Reputation: 195
I have a QVBox layout that houses a QVBox layout and a QHBox layout. I use the other QVBox layout to hold dynamically created GUI objects and the QHBox layout to hold the buttons that add/remove those objects. Everything works correctly if I position the QHBox on top of the QVBox, but when I try to position the QHBox beneath the QVBox the objects aren't removed correctly but stay there "lingering" on top of the QHBox. I'll upload pictures to demonstrate the problem. First picture is before taking action, second is after creating a new object and third is after deleting the object
Here is the code that creates and deletes the new objects
def addClient(self):
if (len(self.clients) < 5):
client = clientComponent(self)
self.clients.append(client)
index = len(self.clients)-1
self.vLayout3.addWidget(self.clients[index])
client.setIndex(index)
self.clients[index].startButton.clicked.connect(partial(self.threadcontrol, '2', client.getIndex()))
self.clients[index].stopButton.clicked.connect(partial(self.clientstop, '0', client.getIndex()))
def deleteClient(self):
if (len(self.clients) > 1):
self.vLayout3.removeWidget(self.clients.pop())
This is where I complete the layout
def initializeUi(self):
self.mainWidget = QWidget(self)
self.setCentralWidget(self.mainWidget)
self.mainLayout = QVBoxLayout(self.mainWidget)
self.hLayout1 = QHBoxLayout()
self.hLayout2 = QHBoxLayout()
self.vLayout1 = QVBoxLayout()
self.vLayout2 = QVBoxLayout()
self.vLayout3 = QVBoxLayout()
self.addServer()
self.addClient()
self.serverBox = QGroupBox('Server')
self.clientBox = QGroupBox('Client')
self.traffic1 = QLabel('0.0Mb/s', self)
self.traffic1.setAlignment(Qt.AlignRight)
self.traffic2 = QLabel('0.0Mb/s', self)
self.traffic2.setAlignment(Qt.AlignCenter)
self.traffic3 = QLabel('0.0Mb/s', self)
self.traffic3.setAlignment(Qt.AlignLeft)
self.newClientButton = QPushButton('+', self)
self.deleteClientButton = QPushButton('-', self)
self.hLayout1.addWidget(self.traffic1)
self.hLayout1.addWidget(self.traffic2)
self.hLayout1.addWidget(self.traffic3)
self.hLayout2.addWidget(self.newClientButton)
self.hLayout2.addWidget(self.deleteClientButton)
self.vLayout2.addLayout(self.vLayout3)
self.vLayout2.addLayout(self.hLayout2)
self.mainLayout.addWidget(self.plot)
self.mainLayout.addLayout(self.hLayout1)
self.serverBox.setLayout(self.vLayout1)
self.mainLayout.addWidget(self.serverBox)
self.clientBox.setLayout(self.vLayout2)
self.mainLayout.addWidget(self.clientBox)
Upvotes: 0
Views: 1687
Reputation: 5000
This is happening because your main window remains the parent of the client widgets after you remove them from the layout. You will see similar behaviour if you assign a widget a parent widget without adding it to any layout.
Removing the parent should resolve the issue.
def deleteClient(self):
if (len(self.clients) > 1):
client = self.clients.pop()
self.vLayout3.removeWidget(client)
client.setParent(None)
You may also need to make a call to adjustSize to resize the window to fit the remaining widgets
Upvotes: 3
Reputation: 2035
When you delete a widget from layout it still remains in parent widget's
object tree, so it gets displayed outside of any layout.
To remove a widget from the object tree call widget.setParent(None)
.
widget.deleteLater()
also works.
Here is my MCVE(Qt4, Py2.7):
from PyQt4.QtGui import (QApplication, QWidget, QPushButton,
QVBoxLayout, QHBoxLayout)
app=QApplication([])
self = QWidget()
main_layout = QVBoxLayout(self)
clients = []
l2 = QHBoxLayout()
main_layout.addLayout(l2)
b_add = QPushButton('add', self)
l2.addWidget(b_add)
def addClient():
b = QPushButton(str(len(clients)), self)
clients.append(b)
main_layout.addWidget(b)
b_add.clicked.connect(addClient)
b_rm = QPushButton('rm', self)
l2.addWidget(b_rm)
def deleteClient():
b = clients.pop()
main_layout.removeWidget(b)
# comment out two following lines to get the behavior you observe
b.setParent(None)
self.adjustSize()
b_rm.clicked.connect(deleteClient)
self.show()
app.exec_()
On my system I also have to call self.adjustSize()
after deletion to resize the main window
Upvotes: 1