How to let user vertically resize window - c++

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.

Related

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

Lay out an image on a Qt dialog

How to add an image to a dialog in Qt?
I know this has been often asked in the past and most answers come up with a QLabel and its setPixmap member. However, this usually is not what the user (me) intends:
A QLabel with a pixmap set does not participate in the surrounding QLayout. That is, it simply refuses to resize when the dialog is resized, like e.g., a QPushButton would do. Two QPushButtons next to each other in a QHorizontalLayout will (something like) equally divide the available horizontal space between them. A QLabe with a pixmap next to a QPushButton in the same layout will just stay fixed in size.
By default, a naked QLabel won't resize its contents when it's resized.
But when it does (QLabel::setResizeContents) it won't keep aspect ratio.
Is there any native way to have a pixmap shown on a dialog and have it reasonably participate in the layout?
Item resizing can be managed via sizePolicy property. From Qt documentation:
sizePolicy : QSizePolicy
This property holds the default layout behavior of the widget.
If there is a QLayout that manages this widget's children, the size
policy specified by that layout is used. If there is no such QLayout,
the result of this function is used.
The default policy is Preferred/Preferred, which means that the widget
can be freely resized, but prefers to be the size sizeHint() returns.
Button-like widgets set the size policy to specify that they may
stretch horizontally, but are fixed vertically. The same applies to
lineedit controls (such as QLineEdit, QSpinBox or an editable
QComboBox) and other horizontally orientated widgets (such as
QProgressBar). QToolButton's are normally square, so they allow growth
in both directions. Widgets that support different directions (such as
QSlider, QScrollBar or QHeader) specify stretching in the respective
direction only. Widgets that can provide scroll bars (usually
subclasses of QScrollArea) tend to specify that they can use
additional space, and that they can make do with less than sizeHint().
I think you are searching for QSizePolicy::Expanding size policy:
The sizeHint() is a sensible size, but the widget can be shrunk and
still be useful. The widget can make use of extra space, so it should
get as much space as possible (e.g. the horizontal direction of a
horizontal slider).
Set this for your QLabel and check how it will resize. Try other values from QSizePolicy::Policy enum.

Qt QGraphicsView - layout not shrinking & sizeHint, minimumSizeHint, etc. not called

I have the following, quite simple setup:
In a QWidget that is displayed as a window (no parent), there is a single QVBoxLayout.
In that QVBoxLayout, there is a single custom QGraphicsView.
The size policy of that custom QGraphicsView is set to Preferred/Preferred and setHeightForWidth set to true (and overwritten in the custom class) - I want to preserve aspect ratio.
The whole constructor of the widget here:
graphicsView = new CustomGraphicsView();
QVBoxLayout *layout = new QVBoxLayout();
layout->setMargin(0);
QSizePolicy sp(QSizePolicy::Preferred, QSizePolicy::Preferred);
sp.setHeightForWidth(true);
graphicsView->setSizePolicy(sp);
layout->addWidget(graphicsView);
setLayout(layout);
The setup works, and the aspect ratio is maintained when dragging the width of the window bigger (the height grows with it).
But as soon as I drag the window width smaller, the aspect ratio of the graphics view is maintained, but the height of the window itself won't shrink. The result being a small graphics view with lots of space above and below it that shouldn't be there.
Investigating it further I was trying to find out where things break, so I overloaded all the sizeHint(), minimumSize(), minimumHeight(), etc. functions of my custom graphics view.
Just to discover that not a single one of them is ever being called while I am manually resizing the window. The only thing called as expected is heightForWidth - which returns my calculated value - but its return value is not applied when the window is shrinking.
So, not only do I not know why the layout won't shrink on its own despite having the Preferred vertical policy (which explicity says "The widget can be expanded, but there is no advantage to it being larger than sizeHint()").
I also don't know how the layout gets the size from the widget to begin with. I assumed sizeHint() since all of the documentation permanently refers to it, but that is obviously wrong in this case.
What I already tried is to set the vertical policy to every possible value. None of them would cause the window to grow and shrink as it is supposed to.
My current workaround:
I have added the resizeEvent(...) function to the widget and inside that, I manually resize() the whole widget if its height exceeds the value returned by the heightForWidth() function of the custom graphics widget.
Okay as far as workarounds go, but it leads to heavy flickering (as usual when resizing inside a resizeEvent).
Any ideas on either problem?

How to resize splitter widgets programmatically in Qt?

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.

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.