PyQT6 QSplitter, QGridlayout with a stretch factor?

54 views Asked by At

Utilizing PYQT6 I want to be able to set multiple frames on it. One of the frames needs to dynamically resize as the user increases or decreases the overall dimensions of the UI. I initially started off with a QGridlayout, but I couldn't find any way to scale the efficiently. So I eventually came across QSplitter

Using QSplitter I implemented something like this.

import sys

from PyQt6.QtCore import Qt
from PyQt6.QtGui import QColor, QLinearGradient, QPainter
from PyQt6.QtWidgets import (
    QApplication,
    QFrame,
    QHBoxLayout,
    QSplitter,
    QWidget,
)

LIGHT_BLUE = QColor(0, 102, 153)
WHITE = QColor(255, 255, 255)


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)

        bottom = QFrame(self)
        bottom.setFrameShape(QFrame.Shape.StyledPanel)

        v_splitter = QSplitter(Qt.Orientation.Vertical)

        h_splitter = QSplitter(Qt.Orientation.Horizontal)
        h_splitter.addWidget(left)
        h_splitter.addWidget(right)
        h_splitter.setStretchFactor(0, 1)
        h_splitter.setSizes([150, 50])
        h_splitter.setStyleSheet("QSplitter::handle {image: none;}")

        v_splitter.addWidget(h_splitter)
        v_splitter.addWidget(bottom)
        v_splitter.setSizes([150, 50])
        v_splitter.setStretchFactor(0, 1)
        v_splitter.setStyleSheet("QSplitter::handle {image: none;}")
            
        hbox.addWidget(v_splitter)
        self.setLayout(hbox)
        self.setGeometry(300, 300, 300, 200)
        self.setWindowTitle("QtGui.QSplitter")
        # self.setStyleSheet("background-color: yellow;")
        self.show()

    def paintEvent(self, event) -> None:

        painter = QPainter(self)
        grad1 = QLinearGradient(0, 0, 0, int(event.rect().height() * 0.22))
        grad1.setColorAt(0.0, WHITE)
        grad1.setColorAt(1, LIGHT_BLUE)

        painter.fillRect(event.rect(), grad1)

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

if __name__ == "__main__":
    main()

This does exactly what I want it to do in regards to the resizing. I can even hide the handles of the QSplitter by setting the styleSheet. The top left frame scales up and down as the overall UI is resized by the user.

The Right and Bottom frames remain the same size. This is exactly what I need it to do. However, the issue that I have is that the user can still hover over the divided area, grab the handle, and resize the frames.

I've not been able to find anything related to the QSplitter handle that will allow me to disable the ability to resize the splitter by grabbing the handle.

This honestly just sounds like a QGridlayout, but with an implementation of stretchFactor. Which doesn't seem to exist.

How would you go about implementing this?

0

There are 0 answers