qtqt-designer

How to equally distribute the width of QSplitter


I have a problem with adjusting width of QSplitter. I prepared UI in Qt Designer and it looks now like that:

Designer view:

enter image description here

And here is my object inspector:

enter image description here

My question is how to divide the width of QSplitter equally over the left and right area. I would like to get this effect as initial size and then the customer can do whatever he wants.

Effect which I would like to have is the following:

enter image description here

In other worlds, I am looking for a way to specify the splitter initial division of left and right area as 50%/50% of window width. Is there any option to obtain that?

Thank you for your help and please be forgiving, I have just started to learn Qt.


Solution

  • Short answer

    splitter->setSizes(QList<int>({INT_MAX, INT_MAX}));
    

    Note: The fine tuning section may contain essential information if you want other ratios.

    Explanation

    1. QSpacer? No.

    You do not need a QSpacer in this case. The goal of a spacer is to fill all available space.

    QSplitter provides two methods to specify the size of its children:

    2. QSplitter::setStretchFactor? No.

    Although the stretch factor may seem to be what you are looking for to specify the relative size of the child widgets, it has the disadvantage for your case that the factors are relative to the initial size of the child widgets:

    stretch is not the effective stretch factor; the effective stretch factor is calculated by taking the initial size of the widget and multiplying it with stretch.

    Therefore, setting the stretch factor for both children to the same value (ex. 1) will not work well:

    splitter->setStretchFactor(0, 1);
    splitter->setStretchFactor(1, 1);
    

    3. QSplitter::setSizes? Yes.

    A better alternative is to use setSizes, because only the relative sizes matter:

    The overall size of the splitter widget is not affected. Instead, any additional/missing space is distributed amongst the widgets according to the relative weight of the sizes.

    So, one could think that setting both sizes to one will distribute the total size equally over both children:

    splitter->setSizes(QList<int>({1, 1}));
    

    No, because you should take into account that the minimal size policy will be enforced by replacing too small values with their minimal size:

    The size policies of the widgets are preserved. That is, a value smaller than the minimal size hint of the respective widget will be replaced by the value of the hint.

    So, you should use a value that is greater than the minimal size of your children, for example the greatest number that can be represented with an int, i.e. INT_MAX:

    splitter->setSizes(QList<int>({INT_MAX, INT_MAX}));
    

    Fine tuning

    As suggested in the comments, INT_MAX may result in some overflow issues, depending on the calculations Qt does with those values. This may be especially the case if you want a non-equal distribution ratio. Therefore, a more sensible large value may be the desktop width/height.

    // Horizontal splitter
    int largeWidth = QGuiApplication::primaryScreen ()->virtualSize ().width ();
    splitter->setSizes(QList<int>({largeWidth , largeWidth}));
    
    // Vertical splitter
    int largeHeight = QGuiApplication::primaryScreen ()->virtualSize ().height ();
    splitter->setSizes(QList<int>({largeHeight , largeHeight}));
    

    Further reading

    Most of the time, Qt does a good job giving all widgets an appropriate size, but tweaking it can become very hard requiring some trial and error. Therefore I want to provide some extra resources which may be useful when working with layout management in Qt: