Search code examples
pythonuser-interfacepyqtqsplitter

How to make one widget fixed when using QSplitter


There are three frames: top, middle and bottom. Whenever I resize the bottom frame, the top frame always resizes at the same time. I want to the top frame to keep its size when the bottom frame resizes. How to achieve that?

from PyQt5.QtWidgets import (QWidget, QHBoxLayout, QFrame, 
    QSplitter, QStyleFactory, QApplication)
from PyQt5.QtCore import Qt
import sys

class Example(QWidget):

    def __init__(self):
        super().__init__()

        self.initUI()


    def initUI(self):      

        hbox = QHBoxLayout(self)
        top =  QFrame(self)
        top.setFrameShape(QFrame.StyledPanel)

        middle = QFrame(self)
        middle.setFrameShape(QFrame.StyledPanel)

        bottom = QFrame(self)
        bottom.setFrameShape(QFrame.StyledPanel)
        splitter1 = QSplitter(Qt.Vertical)
        splitter1.addWidget(top)
        splitter1.addWidget(middle)
        splitter1.setSizes([300,300])
        splitter2 = QSplitter(Qt.Vertical)
        splitter2.addWidget(splitter1)
        splitter2.addWidget(bottom)
        splitter2.setSizes([600,400])
        hbox.addWidget(splitter2)
        self.setLayout(hbox)

        self.setGeometry(300, 300, 1000, 1000)
        self.setWindowTitle('QSplitter')
        self.show()


if __name__ == '__main__':

    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

Solution

  • If you want all the frames to resize independently of each other, put them all in the same splitter, like this:

    def initUI(self):
        hbox = QHBoxLayout(self)
    
        top = QFrame(self)
        top.setFrameShape(QFrame.StyledPanel)
        middle = QFrame(self)
        middle.setFrameShape(QFrame.StyledPanel)
        bottom = QFrame(self)
        bottom.setFrameShape(QFrame.StyledPanel)
    
        splitter1 = QSplitter(Qt.Vertical)
        splitter1.addWidget(top)
        splitter1.addWidget(middle)
        splitter1.addWidget(bottom)
        splitter1.setSizes([500,300,200])
    
        hbox.addWidget(splitter1)
        self.setLayout(hbox)