Sizing of Qt Dialog Window Refusing to Change - c++

I am trying to change the size of a QT dialog window from within the .ui file. The preview of the window in my .ui looks like this.
However, when I run my program, it ignores the sizing policy I have imposed on the window. And it looks likes this :
I have changed the size Policy to minimum (rather than my usual Fixed) for everything within the window just to check. But it seems there is some kind of margin at top and bottom that I am unable to get rid of no matter what changes I make.
The topmost QDialog layout has 0 margin everywhere, so it can't be that.
Here is the hierarchy.
And also the relevant properties for the top most layer: ClickThresholdDlg.
Any tips on what it could be much appreciated. Could it be caused by parts of the GUI further down into the hierarchy ? All of the layouts of 0 margin, and the heights for each is the minimum before it starts cutting off text.

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();

Qt - Make QMainWindow to non resizible in Qt Designer

Is it there a way to set a QMainWindow to be non-resizible in Qt Designer? I am seeing lots of coding examples but I want to do as much UI customization in Qt Designer as I can. So far I can only get this by setting the minimum size and maximum size to be equal, but still there is the resize arrow in the corner of the window and a "maximize" button on the top of the window.
When you select the QMainWindow, the properties of the object does contain a field for sizePolicy, both horizontal and vertical, as mentioned by the answer of #jester and you can set those to fixed.
I have found that doesn't always work and was never sure why (perhaps to due to layouts), but as you've found out, if you set the minimumSize and maximumSize fields to the same value, it does what you want.
As for the resize arrow and maximize button, I have never been able to do that from Qt Creator (designer), so I would say it's not possible. However, just one line of code is all you should need in the constructor of your class: -
setWindowFlags(Qt::Window | Qt::CustomizeWindowHint);
By default, the window flags include Qt::WindowMaximizeButtonHint. By setting the above flags, you're stating that you want to customise the window to include the specified elements. This will also remove the minimise button, so if you want that too, you should add Qt::WindowMinimizeButtonHint
I am not using Qt Designer; I am just writing a subclass of QMainWindow made from scratch. The solution I found for having a non-resizable window is to call setFixedSize on the QMainWindow after you have set up all your widgets and layouts. If you have set things up well, then you don't have to pick a size manually; you can just get the size from sizeHint. The line of code I used inside my subclass of QMainWindow is:
setFixedSize(sizeHint());
I tested this in Qt 5.5 on Windows 8.1 and everything looks fine: the maximize button gets disabled but the other buttons are still there, and the cursor does not indicate the possibility of resizing when the user moves it to the border.
use the setFixedSize property for the QMainWindow. In designer, if I remember correctly, you can set the horizontal and vertical sizePolicy to Fixed.
Sadly there is no option to do that; in VS you may find an option in the editor, to remove the mouse trigger that resize the window; but for some reason, QT5 does not have one.
I tried to use sizePolicy and set it as fixed for mainWindow; but this does nothing for both the horizontal and vertical policy.
To solve the problem, I did set my mainwindow minimum and maximum size as the same values; and when you run the application, the mouse cursor won't be enabled for resizing.
It is an ugly way to do something so simple, but this is the only way I found in QT designer, without use code.
I solved the problem of Qt5 which is displaying mouse arrow resize window even with window having fixed size, but in Python, but you can make modifications for C++.
MainWindow.setWindowFlags(QtCore.Qt.MSWindowsFixedSizeDialogHint)
It's an old post but I want to help if someone need it.
I found a way (not so beautiful) but it works directly from QTDesigner.
You can lock the resize by writing the values of height and width also inside "MinimumSize" and "MaximumSize" property.
Oviously also set "Fixed" on vertical and horizontal as told by other users.
This will remove the button to enlarge the window.

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.

Qt window resize problem

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

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.