[Qt-interest] Dynamic Layout Management
John Posner
jjposner at optimum.net
Tue Dec 29 19:43:09 CET 2009
Frank Mertens wrote:
> Shawn Badger wrote:
>
>> Hi,
>>
>> I am running into a problem that I can't seem to find an answer to.
>> My scenario is simple. I have a central widget that contains two
>> child widgets in a horizontal layout, like so:
>>
>> ------------------------------
>> | | |
>> | | |
>> | 1 | 2 |
>> | | |
>> | | |
>> ------------------------------
>>
>> I need the ability to show only widget #1, or #2, or both at the same
>> time, and have the window grow/shrink accordingly. When I hide #1 and
>> then call resize(0,0), the window correctly shrinks to the size of #2.
>> And when I show #1, it grows back to the size of #1+#2. However, if
>> I hide #2, I cannot get the window to shrink down to the size of #1.
>> It's like the size hint does not get updated correctly.
>>
>> Does anyone know how to get the behaviour I am looking for, without
>> having to force a fixed geometry?
>>
>>
>
> Yes, Qt4's layout system has bugs.
> Maybe try a QSplitter, at least it keeps the sizes correctly
> and if it doesn't you can call setSizes().
>
This Python code implements four child widgets, and handles their
removal (via click) correctly. Clicking the frame background restores
the removed widgets, in random order. As far as I can tell, all four
statements in ClickLabel.mousePressEvent() are necessary.
#----------------------
import random
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class ClicklLabel(QLabel):
"""
label that disappears when clicked
"""
def __init__(self, color, wid, hgt):
super(ClicklLabel, self).__init__()
self.setText(color)
self.setAlignment(Qt.AlignCenter)
self.setStyleSheet("background-color: %s;" % color)
self.setMinimumSize(wid, hgt)
self.setMaximumSize(wid, hgt)
def mousePressEvent(self, evt):
"""
remove label from top-level window's layout
resize top-level window
"""
topwin.layout().removeWidget(self)
self.setParent(None)
app.sendPostedEvents()
topwin.resize(1,1)
class ClickFrame(QFrame):
"""
click frame background to restore removed
labels, in random order
"""
def __init__(self):
super(ClickFrame, self).__init__()
def mousePressEvent(self, evt):
random.shuffle(widgets)
map(topwin.layout().addWidget, widgets)
app = QApplication([])
topwin = ClickFrame()
topwin.setStyleSheet("background-color: #ddeeff")
# create label widgets
widgets = [ClicklLabel("cyan", 150, 150),
ClicklLabel("red", 75, 50),
ClicklLabel("green", 200, 200),
ClicklLabel("yellow", 50, 75)]
# lay them out horizontally
topwin.setLayout(QHBoxLayout())
map(topwin.layout().addWidget, widgets)
topwin.show()
app.exec_()
#----------------------
-John
More information about the Qt-interest-old
mailing list