Search code examples
pythonpyside2

Resizing one widget before another


Hi is there a way to resize one widget before another in a layout? For example, when I resize the window, I want one of the widgets to resize to zero first before resizing the other widget. Here is what I have so far:

from PySide2 import QtCore, QtWidgets, QtGui

class TestWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super(TestWindow, self).__init__()
        wgt = QtWidgets.QWidget(self)
        mainLayout = QtWidgets.QHBoxLayout()
        wgt.setLayout(mainLayout)
        self.setWindowTitle("Test")

        l = QtWidgets.QFrame()
        r = QtWidgets.QFrame()

        l.setStyleSheet("background-color: blue;")
        r.setStyleSheet("background-color: green;")

        mainLayout.addWidget(l)
        mainLayout.addWidget(r)            

        self.setCentralWidget(wgt)


app = QtWidgets.QApplication()        
x = TestWindow()

x.show()
app.exec_()

Here are some pictures showing what I want:

Green disappears first, then blue

So in this example, I want the green box to get smaller first, before the blue one does when I resize the main window. How do I achieve this in QT?


Solution

  • I found a workaround for this. I decided to use a splitter for this solution.

    class TitleSplitter(QtWidgets.QSplitter):
    
        def __init__(self):
            super(TitleSplitter, self).__init__()
            self.setStyleSheet("::handle {background-color: transparent}")
            self.setHandleWidth(0)
    
        def resizeEvent(self, event):
            """ Restrain the size """
            if self.count() > 1:
                w = self.widget(0).sizeHint().width()
                self.setSizes([w, self.width()-w])
            return super(TitleSplitter, self).resizeEvent(event)
    
        def addWidget(self, *args, **kwargs):
            """ Hide splitters when widgets added """
            super(TitleSplitter, self).addWidget(*args, **kwargs)
            self.hideHandles()
    
        def hideHandles(self):
            """ Hide our splitters """
            for i in range(self.count()):
                handle = self.handle(i)
                handle.setEnabled(False)
                handle.setCursor(QtCore.Qt.ArrowCursor)
                handle.setAttribute(QtCore.Qt.WA_TransparentForMouseEvents)
    

    Usage:

    split = TitleSplitter()
    l = QtWidgets.QFrame()
    r = QtWidgets.QFrame()
    
    l.setStyleSheet("background-color: blue;")
    r.setStyleSheet("background-color: green;")
    split.addWidget(l)
    split.addWidget(r)
    

    It only works if you have 2 widgets added. Ideally I would probably use a layout for this, but this works well enough for me.