3

I try to create a gui with two main widgets. The window should be resizable. When resized horizontally only one of them widgets should expand. When resized vertically both should expand. Furthermore it should be possible readjust the resize this split horizontally. I illustrated this to make it more clear:

Resize behavior

With tkinter this was easily achievable with the properties expand and fill. In Qt I could use the resize event but I hope that I don't have to do this manually, since this should after all be a common task. I tried toying around with QHBoxLayout but without success unfortunately.

Any help is greatly appreciated. Thanks.

2 Answers 2

8

You need to use the setStretchFactor method on your QSplitter.

An example (modified from the QSplitter example here):

import sys
from PyQt4 import QtGui, QtCore

class Example(QtGui.QWidget):
    def __init__(self):
        super(Example, self).__init__()
        self.initUI()

    def initUI(self):     
        hbox = QtGui.QHBoxLayout(self)
        left = QtGui.QFrame(self)       
        left.setFrameShape(QtGui.QFrame.StyledPanel)
        right = QtGui.QFrame(self)
        right.setFrameShape(QtGui.QFrame.StyledPanel)
        splitter = QtGui.QSplitter(QtCore.Qt.Horizontal)
        splitter.addWidget(left)
        splitter.addWidget(right)
        splitter.setStretchFactor(1, 1)
        splitter.setSizes([125, 150])
        hbox.addWidget(splitter)
        self.setLayout(hbox)
        QtGui.QApplication.setStyle(QtGui.QStyleFactory.create('Cleanlooks'))
        self.setGeometry(300, 300, 300, 200)
        self.setWindowTitle('QtGui.QSplitter')
        self.show()

def main():
    app = QtGui.QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()  

This produces an initial UI that looks like this:

Initial UI

When the image is expanded horizontally, you can see that the left widget stays the same size:

Expanded horizontally

When expanded vertically, both widgets expand:

enter image description here

Finally, the splitter is resizeable:

Resizeable

If you adjust the window size after adjusting the splitter, the left widget will retain it's size and the right will expand/collapse to fill the remainder of the window.

2
  • One more example for pyqt5 - pyqt6 which doesn't have QSplitter option please?
    – Chris P
    Commented Dec 16, 2022 at 10:39
  • @ChrisP I added corrected answer for pyqt6.
    – Ashark
    Commented Jun 10, 2023 at 12:10
2

The Andy's post is not editable, so I add another answer. Updated for PyQt5/PyQt6.

import sys
from PyQt6.QtCore import Qt
from PyQt6.QtWidgets import QWidget, QHBoxLayout, QFrame, QSplitter, QApplication, QStyleFactory

class Example(QWidget):
    def __init__(self):
        super(Example, self).__init__()
        self.initUI()

    def initUI(self):
        hbox = QHBoxLayout(self)
        left = QFrame(self)
        left.setFrameShape(QFrame.Shape.StyledPanel)
        right = QFrame(self)
        right.setFrameShape(QFrame.Shape.StyledPanel)
        splitter = QSplitter(Qt.Orientation.Horizontal)
        splitter.addWidget(left)
        splitter.addWidget(right)
        splitter.setStretchFactor(1, 1)
        splitter.setSizes([125, 150])
        hbox.addWidget(splitter)
        self.setLayout(hbox)
        QApplication.setStyle(QStyleFactory.create('Cleanlooks'))
        self.setGeometry(300, 300, 300, 200)
        self.setWindowTitle('QtGui.QSplitter')
        self.show()

def main():
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec())

if __name__ == '__main__':
    main()  

enter image description here

Not the answer you're looking for? Browse other questions tagged or ask your own question.