Reputation: 2561
Lets, for example, we have QHBoxLayout inside QMainWindow.
Lets we have set of the widgets inside above layout.
But (!) few of widgets have discrete visual representations. In another words they have few states dependent on available space.
For example:
So when the user change the main window size our "dynamic" widgets must show own representation dependent on available space.
How it could be achieved in Qt?
UPD: the closest behavior present in the Microsoft ribbon interface
UPD2: the QML closest behavior present in gif below (on part where window resized by user)
UPD3: more complex example - each panel in the menu panel change content elements view and count that depends from available space
Upvotes: 2
Views: 570
Reputation: 4367
For this answer, I will use Qt-equivalent terms, not the official MS Ribbon terminology.
You are actually looking at a number of layouts, in a pattern like so:
QToolbar
| (Layout)
+--> QGroupBox/QToolButton
| | (Layout)
| +----->Button
| +----->Button
+--> QGroupBox/QToolButton
Let's start with just the QGroupBox
that populates helps sort our buttons into groups.
Consider that our group box may hold both our dynamic QToolButton
and regular widgets. When the available space shrinks, the layout:
minimumSizeHint()
values of the widgets without fixed size policies.qobject_cast
.Qt::ToolButtonTextBesideIcon
to Qt::ToolButtonIconOnly
, we have to collapse a set of three.We can simplify by making each container only able to hold dynamic tool buttons. Then we don't have to deal with tricky issues like fixed sized widgets and we only need to deal with one type of widget.
Microsoft has also helpfully implemented this behavior for us. You can learn a lot about the behavioral constraints of your layout and child widgets by empirical observation. When do groups collapse? If a group collapses, do other groups expand to take up the space? (The answer to that is no, by the way.) How do buttons group together as they collapse? Are some special in how they collapse and expand (constraints on their expansion and collapsing behavior)?
Qt has also implemented several layouts for us to study and get an idea of how they work and how they are different. QGridLayout
is a promising basis, particularly if you do some math to change the row span of widgets on the fly (this is for grouping buttons as they collapse from vertical layout to sets of three horizontal buttons).
Completely answering your question is far too broad to be on-topic on SO, but I hope this info guides you where you need to go.
Upvotes: 1
Reputation: 4869
There's no magic solution for this. You'll need to implement events/actions to take when the container is resized. It can be as simple or complex as you need. There are several different ways to go about actually implementing it, depending on complexity and scope involved (it is just a few items? the whole UI? etc...).
Here is a very basic (crude but effective) example which moves a toolbar to either be on the same line as another toolbar (for wider window) or to its own line (for narrower window). MdiChild
in this case is a QWidget
implementation which, obviously, contains other widgets and manages their layout.
void MdiChild::resizeEvent(QResizeEvent * event)
{
QWidget::resizeEvent(event);
if (size().width() > ui->topToolbarLayout->sizeHint().width() + ui->botToolbarLayout->sizeHint().width() + 30) {
ui->botToolbarLayout->removeWidget(modelsToolbar);
ui->topToolbarLayout->insertWidget(1, modelsToolbar);
}
else {
ui->topToolbarLayout->removeWidget(modelsToolbar);
ui->botToolbarLayout->insertWidget(0, modelsToolbar);
}
}
As you can see it has to take the container size into account, and the most direct way to do that is in the QWidget::resizeEvent()
. You could do anything here you want... change text buttons to icons, hide/show/move stuff... whatever.
Instead of handling the visual changes in the container, you could of course hook up signals/slots to the contained widgets... eg. a custom signal emit availableSizeChanged(QSize size)
from the resizeEvent()
handler connect()
ed to the contained widget(s).
You may find QStateMachine handy to maintain visual state in a formal manner (this is what QML uses for it's state[s]
property and transition system).
You could also implement your own QLayout
as others have suggested. Though the scope of the question itself suggests you may not need to. The question is quite general IMHO. The two examples provided have massive differences in terms of complexity.
Upvotes: 2