I am having some issue with layout in pyqt. After closing the items from the layout still if layout.count() returns the old item count. So I think .close() not really removing items from the layout. Here is a full working example.
import sys
from PyQt4 import QtGui,QtCore
class LayoutTest(QtGui.QWidget):
def __init__(self):
super(LayoutTest, self).__init__()
self.vvbox = QtGui.QVBoxLayout()
self.dvbox = QtGui.QVBoxLayout()
vbox = QtGui.QVBoxLayout()
vbox.addLayout(self.vvbox)
vbox.addLayout(self.dvbox)
self.setLayout(vbox)
self.add_button = QtGui.QPushButton("Add Items")
self.edit_button = QtGui.QPushButton("Remove Items")
self.chk_button = QtGui.QPushButton("Check Items")
self.vvbox.addWidget(self.add_button)
self.vvbox.addWidget(self.edit_button)
self.vvbox.addWidget(self.chk_button)
self.connect(self.add_button, QtCore.SIGNAL("clicked()"), self.addButtons)
self.connect(self.edit_button, QtCore.SIGNAL("clicked()"), self.removeButtons)
self.connect(self.chk_button, QtCore.SIGNAL("clicked()"), self.checkItems)
self.setGeometry(300, 200, 400, 300)
def keyPressEvent(self, event):
if event.key() == QtCore.Qt.Key_Escape:
self.close()
def addButtons(self):
for i in range(0, 5):
self.r_button = QtGui.QPushButton("Button %s " % i)
self.dvbox.addWidget(self.r_button)
def removeButtons(self):
for cnt in range(self.dvbox.count()):
self.dvbox.itemAt(cnt).widget().close()
def checkItems(self):
QtGui.QMessageBox.information(self, 'Count',"You have %s Items in Layout" % self.dvbox.count(), QtGui.QMessageBox.Ok)
def run():
app = QtGui.QApplication(sys.argv)
ex = LayoutTest()
ex.show()
sys.exit(app.exec_())
if __name__ == "__main__":
run()
Just click two times in add button and after that delete the buttons. Then just check for the items. After closing also you will get you have n items in layout.
So what is the best way to remove widget from a layout other than closing ?
Select one or more elements in the Layout window. Right-click inside the Layout window and click Delete. The element is removed from the page layout and the Layout window.
In PyQt, layout managers are classes that provide the required functionality to automatically manage the size, position, and resizing behavior of the widgets in the layout. With layout managers, you can automatically arrange child widgets within any parent, or container, widget.
The QVBoxLayout class lines up widgets vertically. This class is used to construct vertical box layout objects. See QBoxLayout for details.
Your comment is indeed a solution but rather than close
use deleteLater
. It is safer. With a bit of modification, I'd rewrite your method as:
def removeButtons(self):
for cnt in reversed(range(self.dvbox.count())):
# takeAt does both the jobs of itemAt and removeWidget
# namely it removes an item and returns it
widget = self.dvbox.takeAt(cnt).widget()
if widget is not None:
# widget will be None if the item is a layout
widget.deleteLater()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With