How to equally distribute the width of QSplitter

I would suggest a further variation. The points of m7913d all hold and are important. But in my case (Qt5.13.2) I found that setting large enough sizes could still lead to some variations. I do not know why exactly but setting all the stretch factors to one additionally finally behaved like I wanted.

Also note that setting all stretch factors to one but using non-equal (but still large enough to avoid minimum size constraints) sizes with setSizes works, too! For example:

splitter->setStretchFactor(0,1);
splitter->setStretchFactor(1,1);
splitter->setSizes({static_cast<int>(10000 / 1.618), static_cast<int>(10000 - 10000 / 1.618)});

sets a golden ratio split.


Based on m7913d's

To equally divide a splitter use QSplitter::setSizes, each size in the list should be equal. Use QWidget::minimumSizeHint() to determine the size to use. Use the maximum width (for horizontal splitters) or the maximum height (for vertical splitters) of every widget you added to the splitter

// Example for a horizontal splitter
splitter = new QSplitter(Qt::Horizontal, this);
splitter->addWidget(widgetLeft);
splitter->addWidget(widgetRight);
auto equalWidth = std::max(widgetLeft->minimumSizeHint().width(), 
                           widgetRight->minimumSizeHint().width());
splitter->setSizes({ equalWidth, equalWidth });
// Example for a vertical splitter
splitter = new QSplitter(Qt::Vertical, this);
splitter->addWidget(widgetTop);
splitter->addWidget(widgetBottom);
auto equalHeight = std::max(widgetTop->minimumSizeHint().height(),
                            widgetBottom->minimumSizeHint().height());
splitter->setSizes({ equalHeight, equalHeight });

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

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:

1. 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);

2. 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:

  • Qt documentation about layout management
  • A nice summary of layout management in Qt
  • Example: Using multiple QLayout items to draw a calculator

Tags:

Qt

Qt Designer