[PyQt] Timing problem with resizing of main window

John Posner jjposner at optimum.net
Wed Jun 23 20:37:18 BST 2010


In the program below, the main window's central widget is a QFrame that 
*always* contains a control panel (CtrlPanel, subclass of QFrame). 
Pressing the "Create work panel" button inserts another QFrame above the 
CtrlPanel, causing the main window to grow vertically. Pressing the 
"Remove work panel" button removes the work panel, which *should* cause 
the main window to shrink vertically to its original size.

But the main window does not shrink automatically (using CHOICE = 0 in 
line 74). Method MainWin.fix_size() should force the main window to 
shrink, but simply invoking this method after removing the work panel 
(CHOICE = 1) does not have the desired effect. The only thing that works 
for me is using a QTimer to invoke MainWin.fix_size() after a short 
delay (CHOICE = 2).

Note: I also tried invoking update() on various objects -- no luck there.

Can anyone provide some insight into what's going on and/or what I'm 
doing wrong?

Environment: Python 2.6.5; QtCore.qVersion() == 4.5.3

Many thanks,
John


#-------------------------
import PyQt4.QtCore as C
import PyQt4.QtGui as G

class MainWin(G.QMainWindow):
     def __init__(self, parent=None):
         super(MainWin, self).__init__(parent)
         self.setCentralWidget(G.QFrame(self))
         self.ctrlpanel = CtrlPanel(self)
         self.centralWidget().setLayout(G.QVBoxLayout())
         self.centralWidget().layout().addWidget(self.ctrlpanel)

         self.workpanel = None

     def fix_size(self):
         """change window size after removing work panel"""
         self.resize(*self.ctrlpanel.smallsize)

     def create_work_panel(self):
         self.workpanel = G.QFrame()
         self.workpanel.setStyleSheet("background-color: cyan")
         self.workpanel.setFixedSize(self.ctrlpanel.width(), 500)
         self.workpanel.show()

         # insert new work panel into layout, above control panel
         self.centralWidget().layout().insertWidget(0, self.workpanel)

class CtrlPanel(G.QFrame):
     def __init__(self, parent):
         super(CtrlPanel, self).__init__()
         self.mainwin = parent
         self.smallsize = None

         loadbtn = G.QPushButton("Create work panel")
         loadbtn.setFixedWidth(400)
         loadbtn.clicked.connect(self.create_cmd)

         resetbtn = G.QPushButton("Remove work panel")
         resetbtn.clicked.connect(self.remove_cmd)

         self.setLayout(G.QHBoxLayout())
         self.layout().addWidget(loadbtn)
         self.layout().addWidget(resetbtn)

     def create_cmd(self):
         """create work panel"""
         if self.mainwin.workpanel:
             return

         # save dimensions, for restoration by remove_cmd()
         if not self.smallsize:
             self.smallsize = (self.width(), self.height())

         self.mainwin.create_work_panel()

     def remove_cmd(self):
         """remove work panel"""
         if not self.mainwin.workpanel:
             return

         if not self.smallsize:
             self.smallsize = (self.width(), self.height())

         # find important objects in main window's QFrame
         for obj in self.mainwin.centralWidget().children():
             if isinstance(obj, G.QLayout):
                 layout = obj
             elif isinstance(obj, G.QFrame):
                 workpanel = obj

         layout.removeWidget(workpanel)
         workpanel.deleteLater()
         self.mainwin.workpanel = None

         # restore original window height -- set CHOICE to 0, 1, or 2
         CHOICE = 0

         if CHOICE == 0:
             # DOES NOT WORK: allow main window to resize automatically
             pass
         elif CHOICE == 1:
             # DOES NOT WORK: resize main window immediately
             self.mainwin.fix_size()

         elif CHOICE == 2:
             # WORKS: resize main window after pause
             self.fixit = C.QTimer(self)
             self.fixit.setInterval(50)
             self.fixit.setSingleShot(True)
             self.fixit.timeout.connect(self.mainwin.fix_size)
             self.fixit.start()

# main program
app = G.QApplication([])
vcalc = MainWin()
vcalc.show()
app.exec_()
#-------------------------


More information about the PyQt mailing list