How to resize splitter widgets programmatically in Qt? - c++

I use QSplitter to place some widgets side by side.
Being a user, I can resize those widgets just dragging a splitter.
Being a programmer, I don't know how to specify exactly what width and what height do I want at the moment.
That's my original state (adjusted by different stretches).
I tried to use setFixedSize(), but after that call the user can't resize widgets by itself anymore (and that's definitely correct behavior, because the size gets 'fixed').
If I use resize(), it has almost no effect. The widget is resized, but (!) incorrectly and (!) when I start dragging again the widget gets its initial state.
Is there any way to resize that left widget in code correctly? I don't want to have fixed size but resize() doesn't work properly, as you can see. So what should I do?

QSplitter hast its method QSplitter::setSizes(QList<int>) where each entry in the list is the size of the widget in pixels, from left to right or top to bottom respectively. The method does not require you to know the exact width, it still works with guessed sizes.
I use this functionality for instance to store the user defined sizes (obtained by QSplitter::sizes()) in a QSettings instance on the program shutdown and reapply them when the software is started again. If they are not set for some reason I just set the overall width divided by the number of widgets in the splitter and it works fine enough as an initial state.

Related

How to draw Qt widgets in a QTabWidget in non-selected tabs?

My QTabWidget has 2 tabs on launch.
Tab 1 is the one that's opened upon launch.
Tab 2 contains some widgets of which I take the QSize to later draw similar elements in newly opened tabs.
The problem is that currently the size of the elements is 640x480 (apparently the default value), if tab 2 was not shown yet. Once tab 2 is selected, the elements are "drawn" and get their sizes depending on resolutio, window size etc.
How can I force the drawing of the elements in the background without opening tab 2, so that I can obtain the sizes the elements would have if the tab was opened? repaint and update do not do that.
My current workaround is to launch with tab 2 open and switch to tab 1 in main.cpp between myWindow.show() and myApp.exec() but that seems a bit dirty.
For performance reasons, a QWidget's size() method is not guaranteed to return its expected value until after the QWidget has actually been laid out and shown.
If you need to know in advance what a QWidget's size would be, you can call its sizeHint() method instead, and that will force the calculation to be performed right away, so that the correct size can be returned even if it hasn't already been computed.
according to Document resizeEvent was never called when the widget is not visible and also paintEvent. this is a normal routine for decrease processing effort and reduce the rendering process. if you want to know when a tab1 resized, reimplement(override) resizeEvent and say to tab2 must be resized.

GTK3 No resize limits

Currently if I make a window in GTK3
For example 300x300
And I put a button at the bottom, right hand corner, I can not shrink my window
Size because this button is preventing me is there a function in gtk3 that can allow me to ignore all widgets, and resize to anything even 0x0
And this is the user doing this with the window resize, drag and click
And is there a way where I can set this resize limit myself, and not have this dependent on whats in my window
If you initially use set_size_request() to set the window to 300x300, then it won't shrink below that. To allow users to shrink below an initial value, use set_default_size(). I seem to have read that the minimum size of a widget is 1x1, which seems logical, as, at 0x0 you wouldn't be able to resize it anymore. If you want less than 1x1, you can use hide() and just hide the contents.
But if you have any widgets inside the window, then the minimum size is determined by the widgets! (Called the 'natural size')
To allow a window smaller that than the one determined by the widgets, you can maybe use a Gtk.ScrolledWindow.
Also, recall that the outer border is drawn by the window manager, NOT by Gtk. However, you can disable the outer border by using set_decorated(). Not that this may not work - depending if the window manager respects this (not Gtk's fault).

How to let user vertically resize window

I want the user to be able to vertically resize the Window but I'm unsure how I would do this. I have selected my root object (View of type QWidget) in Qt Creator but I do not see an option to allow users to vertically resize the object. Does this have to be done through code?
By default, if a QWidget is the top-level window you are able to resize it given that the minimumSize and maximumSize are different since they indicate the range of resizing.
If you want to let the user to resize vertically only, then you just have to set both minimumWidth and maximumWidth to the same value (probably to the current width of your QWidget). Qt will take care of indicating the underlying windows manager the rest.
You can do it in the Designer or programmatically using the setMinimumWidth and setMaximumWidth methods. Edit: As mentioned in a comment, there is a setFixedWidth method that simplifies this operation (and make it more explicit in your code).
Of course, you can play with the combinations such as setting a minimum width (or height, or both -minimum size-) to avoid your top-level window to collapse and become unusable, setting a maximum size... One common setting is making minimumSize = maximumSize, so you make the window fixed size (you can use the convenience method setFixedSize).
PS: see that this has nothing to do with the sizePolicy, which simply indicates parent layout which actions can be taken -regarding size- when placing the widget. As a top-level window has no parent layout this policy is simply not used.

Enlarge a Qt widget so it might cover other widgets

I have a complex layout of widgets in widgets in widgets in a QMainWindow. In one of them I have an image, it sits in the corner. What I would like to achieve is following: if the image is activated (e.g. clicked upon), it should be enlarged, so it might overlap other widgets, or parts of other widgets. The problem is, I still would like it to remain in the layout, but in a way that everything else remains in its original size and position.
I was thinking about having an empty but similar size widget as a "placeholder", and have the actual resizable widget float on top of it. My problem is, that it does not guarantee that it stays in its position if the main window is resized, maximized, etc. Is there a better or more efficient way to do it?
One way to do it, if the widgets to be overlapped are in the same layout than the one you want to enlarge, and the policies for that widget allow it, is just .setVisible(false) in the other widgets. The widget that remains visible should resize to cover all the available area!
If I can't find a better solution, I think I'll do the following:
The MainWindow will have no layout, just two QWidgets on top of each other. The bottom one will contain all the layouts and everything else, while the upper one will have a transparent background and the resizable widget, maybe supported with a number of spacers.

In Qt, how do I make a dialog un-resizeable, yet automatically adjusting its size to the contents?

I have an instance of QDialog, populated by widgets using code generated by uic. The dialog contains a few labels laid out vertically, and I am popping the dialog from time to time to show some text in these labels. The text can be multi-line and its length is not pre-determined. I set the vertical size policy to fixed, so the user can't drag it (doesn't make sense), but I also want the dialog to change its size before being shown to accomodate for the current size of the labels.
To this end, I was calling QWidget::adjustSize() on the QDialog before displaying it, but it doesn't work as expected. When the dialog is shown, it seems to retain the (wrong) size from the previous displaying, but when I click the mouse in the (disabled) vertical resize mode, the dialog suddenly "snaps" to the (correct) adjusted size.
Is there any way to make my dialog appear correctly?
EDIT: I tied rubenvb's advice, and ended up with this:
QSizePolicy free(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
QSizePolicy fixed(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
dialog->setSizePolicy(free);
dialog->adjustSize();
dialog->setSizePolicy(fixed);
dialog->show();
Unfortunately, that didn't seem to change anything.
This isn't the answer you're hoping for, and it may not apply to what you're trying to do, however, the only way that I was able to adjust the dimensions of a QWidget at run-time was by handling the object's resizeEvent(..) method. This allowed me to calc the size of items based upon the font being used, number of lines, available space, etc., and then adjust their size accordingly before passing the 'event' on to the base resizeEvent(..) method.
My approach used a single QWidget container within a window, below a header, above a footer status area, and to the right of a column of menu buttons. The widget container, inside the resizeEvent() call, would look at the objects it was going to display, calculate the font heights being used, and then resize some items according to their dimensions (because of how the style sheet selected fonts and colors, etc) and then adjust the sub-widget dimensions before allowing the container widget to get the resizeEvent() message.
So I wasn't so interested in setting a window size, but I think the container QWidget might work the same way? I was more interested in setting the dimensions to some asthetically pleasing size, depending upon the dimensions of the display.
Hope you find that helpful.
Do everything in the right order:
Dialog is not shown. Dialog is resizeable.
Calculate new size, set new size.
Set dialog to not-resizeable.
Show Dialog.
Hide dialog, go to step one.