Prevent QDockWidget autosizing behaviour - c++

Qt 5.5.0
In my application, I have a QGraphicsView as the main widget and a QDockWidget for properties.
The goal is for the user to select an item in the graphics view and, depending on the item, present the appropriate properties for that item.
I achieve this by having a properties manager widget with a layout containing each of the properties widgets. I have signals and slots hooked up for getting the currently selected item, and then show() the widget I need and hide() the rest.
This works great! However, when selecting different items, the dock shrinks or grows based on the shown widget. It is very jarring, and rather annoying. The thing is though, that when the user manually resizes the dock, it maintains that size. I want the maintained size to be default rather than this autosizing behaviour.
Things I've tried:
I've tried changing the sizePolicy() of the dock and the mainwindow: No effect.
I've set a minimum size for my properties manager which does indeed prevent the dock from shrinking when a smaller set of properties is shown. However, I still want the user to be able to shrink the dock to a smaller size if they wish, and this method prevents that...
Conclusion:
Is there a flag or something that is set when the user resizes the dock that tells it to maintain that size? If so, is there a way to manually set it?
I haven't tried subclassing QDockWidget or QMainWindow yet. Is there a method(s) that I can override to achieve the correct behaviour?
Thanks for any help!

All that was necessary was to call
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
in the constructor of my properties manager widget (the central widget of the QDockWidget)
I also overloaded the sizeHint() function to return a respectable default size.

First, create your dock widget:
QDockWidget *dock = new QDockWidget;
Now set size policy to dock's widget.
If dock is vertical:
dock->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Expanding);
If dock is horizontal:
dock->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Ignored);
Set your widget to dock:
QWidget *myWidget = new QWidget;
dock->setWidget(myWidget);
Now set size policy to dock's widget.
If dock is vertical:
dock->widget()->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Expanding);
If dock is horizontal:
dock->widget()->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Ignored);
Finally, add dock to main window:
If dock is vertical:
mainWindow->addDockWidget(Qt::LeftDockWidgetArea, dock);
mainWindow->resizeDocks({dock}, {0}, Qt::Horizontal);
If dock is horizontal:
mainWindow->addDockWidget(Qt::TopDockWidgetArea, dock);
mainWindow->resizeDocks({dock}, {0}, Qt::Vertical);

Related

Qt dock neighbour widget behaviour

I have two Qt widgets in the window. One of them is QDockWidget, and another one is just QWidget.
When I drag the QDockWidget, the default behaviour of the another widget is moving without changing its size. And I want it to fill the whole window except dock widget, and to change its size programmatically when I drag QDockWidget. Hwo to do it better?
The solution was to set container horizontal policy as "fixed"

QWidget within scrollarea

I have a QWidget that I want to include within a scroll-area so that when the designated QWidget size is exceeded vertically, the user can scroll up and down to see more.
QWidget renameWidget;
QScrollArea scrollarea.
How do I go about doing this? I set the widget inside the scroll-area on the UI editor but it didn't work.
Any ideas?
Thanks.
Think of QScrollArea as another layout. Add the scroll area to your main widget and put everything else inside it with setWidget().
QScrollArea is QWidget, so you can even use it as a top level widget:
QScrollArea *scrollArea = new QScrollArea();
scrollArea->resize(250, 250);
QWidget *widget = new QWidget(scrollArea);
widget->setBackgroundRole(QPalette::Dark);
widget->resize(200, 200);
scrollArea->setWidget(widget);
scrollArea->show();
QScrollArea provides a scrolling view onto another widget. It is used to display the contents of a child widget within a frame. If the widget exceeds the size of the frame, the view can provide scroll bars so that the entire area of the child widget can be viewed.
An example:
QScrollArea *scrollArea = new QScrollArea(this);
scrollArea->setBackgroundRole(QPalette::Dark);
scrollArea->setWidget(renameWidget);

How to expand widgets with window resize?

I have a simple qt application with a QTabWidget inside the main window. I also have a few QPushButton(s) and QRadioButton(s).
What I want is that when I resize the window either manually or by maximizing/minimizing it should resize the containers in the same way.
In other words, what I want is equivalent of DockStyle.Fill in qt C++
How can I do that ?
In Qt you have to use Layouts:
The Qt layout system provides a simple and powerful way of automatically arranging child widgets within a widget to ensure that
they make good use of the available space.
In short, all components in a layout will be relocated to new places after the window, to which the layout belongs, is resized.
If you are using deisgner:
1. Click the empty space of a widget to select itself(or a main Window, I use just a base widget here for demonstration), and the layout option will be hightlighted:
2. Choose a desired layout
Here is what object monitor looks like after a QVBoxLayout is used:
If your widget doesn't use layout, it will look like this:
What we have done here is to make the base widget/mainWindow equip a main layout. You can see that the buttons are automatically aligned, when you resize the widget, those component will be relocated according to the layout:
Perhaps you will find it nettlesome of those expanding space, so the next move is to add a Spacer to the layout; so when layout is resized, only the spacer will stretch.
(Another option is to make your widgets expandable, see ** at the end of this post)
3. Besides, you can add a layout into another to create a nested layout
For example, first I choose A and B (by pressing Ctrl) and use QVBoxLayout. This additional layout is not base layout and hence highlighted by red rectangle.
Then I choose C and the layout which contains A & B, and use QHBoxLayout on them,
Finally I use another QVBoxLayout as my main layout on the base widget, just like what we did previously.
And the object monitor:
If you like the special feeling of hitting keyboard and always handcraft the code:
For the last example:
QWidget *Form = new QWidget;
QPushButton *pushButton_A = new QPushButton("A");
QPushButton *pushButton_B = new QPushButton("B");
QPushButton *pushButton_C = new QPushButton("C");
QVBoxLayout *verticalLayout = new QVBoxLayout;
QHBoxLayout *horizontalLayout = new QHBoxLayout;
QVBoxLayout *mainLayout = new QVBoxLayout;
verticalLayout->addWidget(pushButton_A);
verticalLayout->addWidget(pushButton_B);
horizontalLayout->addWidget(pushButton_C);
horizontalLayout->addLayout(verticalLayout);
mainLayout->addLayout(horizontalLayout);
Form->setLayout(mainLayout);
Form->show();
In your case
Here is an example of layout:
Notice that QMainWidget has a centralwidget as a base widget. Besides, each tab of QTabWidget has it's own base widget (tab and tab_2 in the picture) which adopts another base layout.
*Don't forget to add Spacer in layouts to shape them as you like.
** You can set size policy on each widget (QTabWidget, QPushButton etc) to make them horizontally/vertically expandable or fixed, this cooperates with the layout strategy. For example, in the very begin example if we set
button A to be vertically fixed, horizontally expanding
button B to be vertically expanding, horizontally expanding
button C to be vertically expanding, horizontally fixed
It will look like this when resizing:
you need to look into how to use layouts in your application
http://qt-project.org/doc/qt-4.8/layout.html
As a quick and simple first try, in the Designer you can right-click on the main window, and choose "layout" from the drop-down menu. Here you can pick the grid layout, for instance.

Adding scroll bar to widget containing a layout in QT C++

I am new to QT and I am creating a widget that has a gridlayout. The gridlayout contains a matrix of QLineEdit widgets. The window resizes to fit the layout but when layout is large it goes off screen. When I maximize the screen, the QLineEdit widgets are resized to fit the screen and for large layouts they become extremely small.
I want to be able to resize the window without resizing the QLineEdit widgets and add scroll bars to navigate.
I tried the following with no luck:
Window->resize(QSize(500,500));
QScrollArea *scrollArea = new QScrollArea;
scrollArea->setWidget(Window);
where window is the widget containing the layout. Also, the window closes when after executing "scrollArea->setWidget(Window);" and I dont why.
If someone can help me out I would really appreciate it.
Thank You!
For disabling the vertical resize on the widgets, why don't you just use the setFixedHeight() method on the widgets?
For the menu bar, why don't you take it out of the widget that is scrollable. You can have a layout for the window that contains the menu bar and then the widget that contains everything else (scrollable part). Is that what you are looking for?
I fixed my problem by creating a QMainWindow with the menu bar. Then created a widget which includes the layout, set the Scroll Area to the widget. Finally set the central widget of the main widow to the scroll area.

resize problem in scroll area

Hello everyone, here is my code:
myplot *p = new myplot(gao.structpayloadgraph,
gao1.structpayloadgraph,
gao.structcol-2, "payload");
ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
ui->scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
ui->scrollArea->setWidgetResizable(false);
p->resize(ui->scrollArea->size().width(), ui->scrollArea->size().height());
ui->scrollArea->setWidget(p);
I want p to take up the full available space of the scrollbar area and fit itself. However, the appearance looks 'squeezed' even though I called the resize function. What should I do to achieve the desired effect?
You have to treat the scroll area content widget as a normal QWidget. If you want automatic resize and you must use layouts in Qt. Try the following :
QVBoxLayout layout = new QVBoxLayout( ui->scrollAreaContent);
layout->setMargin(0);
layout->setContentsMargins(0,0,0,0);
layout->setSpacing(0);
ui->scrollAreaContent->setLayout( layout);
layout->addWidget(p);
NOTE: ui->scrollAreaContent is a guess, but I think you are using ui files and default content widget is named like that ...
Go to the top right of the QT creator designer screen (Object, Class), right click on the QScrollArea row and select the "Lay Out" menu item, choose a layout (eg vertical or horizontal layout), make sure that your QWidget has a minimum or above size policy. Your scroll widget should now resize with the layout.