Qt window resize problem - c++

I am having a problem redrawing a QWidget window after its size has been adjusted. I have tried update(), repaint(), adjustSize(), but all seem to suffer from the same thing: only part of the window is redrawn, resulting in the window frame on the bottom and right sides to not show. The window is also not resized entirely.
Just in case it makes a difference, the window is in a QMdiArea.
Thanks.
// ... some subwidget resizing and moving.
calibrationWindowUIs[activeWindow].layoutWidget2->move(QPoint(oldXLeft, 30 + height + 21));
calibrationWindowUIs[activeWindow].layoutWidget1->move(QPoint(oldXRight, 30 + height + 21));
// Set window size.
calibrationWindows[activeWindow]->setMinimumSize(calibrationWindowUIs[activeWindow].tabWidget->geometry().width() + 40, calibrationWindowUIs[activeWindow].tabWidget->geometry().height() + 40);
calibrationWindows[activeWindow]->update();
Note: I'm new to Qt; perhaps I'm doing something wrong with layouts?
Edit: I may have not given enough information. Alright, to be quite honest, I still have to delve deeper into layouts and related material. What I had tried to do here was to use Qt Designer in order to design the window. I've done what perhaps amounts to a stupid mistake: I didn't use an overall parent layout for the entire window, but hacked it with a couple of smaller layouts that I therefore have to move about and resize individually. See the Qt Designer screen (the red rectangles are the sole layouts): .
What is happening is that in the frame to the right, I am playing a video clip that can be of various resolutions. I want the frame to resize depending on this resolution, which also means that the buttons and window have to move/resize accordingly. That is where the window resize comes in. I'm sure there is a more elegant solution than what I am doing here, but I am trying to handle several other scenarios here and hence the lack of quality of code.
The result is that when I load a clip, the window attempts to resize, but does so badly; the following is the result:
If the window is dragged, it 'pops' into its correct size; in the meantime, however, it just looks ugly.
A couple further questions: do you use the Qt Designer to design your UIs? I found that programmatically you can achieve much better control of your interfaces. One thing which I could not do in the designer was to have a layout parented by the main widget, i.e. the equivalent of having the following bit of code:
QVBoxLayout* layout = new QVBoxLayout;
this->setLayout(layout);
A layout placed in the designer always seems to create this 'layoutWidget' subwidget, which the layout you placed is then parented to. Any way around that?

We use a mix of designer and code to create layouts, the Qt layout system can be very unintuitive at times. But I would probably not layout a full series of tabs in one designer ui file, i would make each tab each own widget and then assemble them either through code or in the designer by promoting to custom classes. This gives you better separation of responsibilities, by putting all the functionality of all the tabs into one file you almost guarantee a large unwieldy class.
When a widget has child widgets in designer you can assign a layout to it by adding it from the context menu. Make sure nothing is selected and click on the background of the widget in which you want to create a layout, select the layout and all of the widgets children will be assigned the layout.
What does help is creating hierarchies of layouts. Looking at your first screenshot, i would probably use a vertical layout with spacers on top and bottom for the items on the right, an horizontal layout with spacers left and right for the button bar and a grid layout for all the items together. Without the spacers your items will extend when the window grows. The spacers will let you control the behavior under resizing better.

you are calling setMinimumSize(). That's fine, but you should also call resize()

Related

Creating a scrollable window without Layouts

I am trying to achieve something what, I thought, would be a super easy thing to do. But for some reason QtDesigner is driving me crazy, it simply won't work...
I created a GUI and freely arranged different elements in the window, without layout or anything like that. At some point there were to many elements, so all I wanted to to, was to make it scrollable up and down, to see all elements.
So I added a ScrollArea in QtDesigner and added all elements as children of this ScrollArea (which btw also was a pain in the ass, because apparently drag and drop in the Object viewer is not a thing, and editing the .ui file by hand, is also not allowed... great).
So the result I have now is the following:
before resize - no scrollbar, elements at bottom inaccessible
resized vertically - some stuff still snapped off at the bottom
So as you see, although I created a ScrollArea... There is no scroll area. So I googled a little bit and found out that you can add layouts to your scrollarea, and yey, finally, a scroll bar! But how in this world am I supposed to arrange the elements in the way you see in the screenshots, with layouts. They are so super restrictive.
How am I supposed to simply get a vertical scrollbar, without this restrictive layout stuff?!
Here is how my object viewer looks
And here is what is called upon GUI creation:
ui->setupUi(this);
//setCentralWidget(ui->scrollArea);
//ui->scrollArea->setWidgetResizable(true);
I tried it with, and without the commented lines. No scrollbar, no matter what I do.
Try this to fix it:
In Qt Designer:
Select QScrollArea object.
Uncheck the QScrollArea properties widgetResizable.
In C++:
// If you want to set `widgetResizable` programmaticly
ui->scrollArea->setWidgetResizable(false); // Optional if you did it in Qt Designer
ui->scrollArea->widget()->adjustSize();

Resizing a gtk2 widget with the mouse inside an area (window) with scroll?

I wanted to develop a widget container (still on python 2.7 and gtk2), which would be placed in a scrolled window, and could be freely moved and resized in the window, such that: click & drag within the widget would move it inside the window; and when widget's corners / edges are visible in the window, it would expose drag handles for resizing - otherwise, if it is bigger than the window area, it would scale up and down (zoom in and out) on middle-click.
Of course, I want to keep the amount of custom coding of this widget to a minimum, so I though looking into what's available in gtk2 first. It turns out, the only element exposing resize drag handles is gtk.Window - and at that, only if it is a main (or root) window; otherwise, if a window is placed inside a widget, its size is apparently set by the widget, and so there are no drag handles (not menus, titlebars etc). I was wandering why this is - and it seems it is due to multiple document interface (MDI) being considered evil by gtk developers, see e.g. Re: [gtk-list] Resizing widgets with a mouse or Does GTK support MDI? - Linux/BSD whirlpool.net.au.
Just to demonstrate the behavior that I want, I used a PyQt4 code from Python PyQt/PySide QMdiArea subwindows scroll not working in TabbedView - Stack Overflow, since as it turns out, Qt does have an MDI area. So here's the gist of it - if a corner is visible, a resize drag handle appears, and resize drag action can be started:
When you thus drag the corner outside of the window - the scrollbars automatically indicate the new size/position of the inner widget (note the window got also moved a bit in this screenshot below, that was manual and unintended):
Again, I don't really need a window (as in titlebars, menus) - just a widget container that would behave in this way, so I could put e.g. a table (e.g. TreeView) or an image in it, as the situation demands - and at least not worry about recalculating the "outer" scrollbars (naturally, I'd expect I'd have to code the rest of my custom behavior myself). Also, I just need a single widget placed in a window like that for now (so no "multiple document"s).
While Qt seems to offer this in a way, I don't have the possibility right now to get into it to the level of doing something like this; and the same goes for WxWindows (see e.g. wxPython-users - How to resize Widgets? - possible, but as there is no code there, I cannot see if geometry calculation coding is required or not).
So I was wondering - is there a widget I may have missed, that would implement the above behavior, and that I could take as a base for customization? If not, what options do I have to implement something like the above on gtk2 (eventually with Python)?
I'm not sure this would work, but I suggest looking into GtkOffscreenWindow; put the inner widget into that, and render it to a GtkDrawingArea inside a GtkScrolledWindow. This would probably make the scrollbars behave properly depending on the size of the drawing area.
What you won't get:
window titlebars, you'll have to render those yourself because GTK doesn't know about them, they're part of the window manager. (Note, the inner window in the Qt example has a different titlebar than the outer window - I suspect this is the same thing.)
drag handles to resize the window, you'll have to code those yourself, as you expected.
You might also want to look at how the Glade GUI designer does this.

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.

Qt prevent controls moving when window resized

I have a Qt application which has a window based on a QWdiget. Inside my window I have two QVBoxLayouts and one QHBoxLayout with controls underneath the first two Vertical layouts. When my window is resized, the QVBoxLayout move apart and the QHBoxLayout underneath also moves away. I want to prevent this from happening, what is the best way to do this?
All these layouts are inside a QGridLayout.
If I understand your question correctly, you have a window's layout like this :
The layouts is going to resize depending on the size of the objects in them. To solve your problem, you should set the alignment of your layouts within the grid layout using setAlignment method.
by the way, if nothing works, you can always write your own layout manager.

QListWidget that resizes instead of scrolls

How do you change the behavior of a QListWidget so that it resizes its height instead of choosing a (seemingly arbitrary) height and adding scrollbars? See screenshot:
The QListView's should fill up as much space horizontally as they can (creating as many "columns," if you will.) Then they wrap and make as many rows as necessary to fit all the items. These calculations should be adjusted as the window is resized. This is all working fine.
However, what I want to happen is that instead of the height staying the same, the QListView should grow or shrink vertically and never need any scrollbars. The scrolling, if necessary, will be handled on the parent QWidget that hosts all of the labels and lists. It seems like once the height of the QListWidget is established (not sure where its default is coming from), it never changes. It is too big in some cases (see second "Test" list above) and too small in others (see first "blank maps" list above.)
The layout above is nothing surprising: two QLabel's and two QListWidget's in a QVBoxLayout. Here are the properties I have set on the QListWidget's:
setMovement(QListView::Static);
setResizeMode(QListView::Adjust);
setViewMode(QListView::IconMode);
setIconSize(QSize(128, 128));
(I already tried setting the horizontal and vertical scrollbar policies, but that just turns the scrollbars off, clipping the content. Not what I want.)
Maybe you could this without using QListWidget. The Qt's examples contain a new layout class, QFlowLayout, which could be useful. With the following kind of widget hierarchy you could get multiple groups with labels and they all would be inside one QScrollArea.
QScrollBox
QVBoxLayout
QLabel "Blank maps"
QWidget
QFlowLayout
your own widgets showing map images and labels
QLabel "Text"
QWidget
QFlowLayout
your own widgets
The problem is that this kind of solution would create much more widgets than QListWidget based solution. So if you have hundreds of items in your list, this might not be the best solution.
There is a protected member function called contentsSize() in QListView. It is used to calculate the required minimum(), maximum(), and pageStep() for the scrollbars (as mentioned here).
Can you subclass the QListView class and make use of that information? I suggest you recalculate the size of your widget in the same function where you add contents to it. While somewhat lacking elegance, this appears to be a pretty reliable solution.