Non-resizeable QDialog with fixed size in Qt? - qt

I have a Qt dialog application. Now I dont want that dialog to be resizeable. I am not sure how to achieve this. I tried a bunch of things but still when the dialog launches this dialog can be resized.
What is the property that i should set to disable the dialog/Widget resize.
I also tried
setSizePolicy(QSizePolicy::Fixed);
But i get an error saying..
source\nimcac_settingsMain.cpp(36) : error C2248:
**'QSizePolicy::QSizePolicy' : cannot access private member declared in class 'QSizePolicy'**
p:\ThirdPartyExports\Qt\export\4.3\4.3.1f14\include\QtGui\../../src\gui\
kernel\qsizepolicy.h(177) : see declaration of 'QSizePolicy::QSizePolicy'
p:\ThirdPartyExports\Qt\export\4.3\4.3.1f14\include\QtGui\../../src\gui\
kernel\qsizepolicy.h(34) : see declaration of 'QSizePolicy'
Kindly help me out with this.

The compile error you get is because you try to pass a QSizePolicy::Policy to setSizePolicy(QSizePolicy), but there's no implicit conversion from QSizePolicy::Policy (which is the policy for one dimension) to QSizePolicy (which is a class containing, among other things, one Policy per dimension (height, width)). QSizePolicy doesn't work on top-level widgets (windows) anyway, though.
setFixedSize() only works if you know the size of the dialog in advance (and usually you don't, what with changing font sizes and languages). You can do
window()->setFixedSize( window()->sizeHint() );
but it's much better to use
window->layout()->setSizeConstraint( QLayout::SetFixedSize );
That lets the layout determine the size of the dialog, but doesn't allow resizing, which I assume is what you were asking for.

I don't know if you already tried it, but QWidget::setFixedSize should do what you want

this->setFixedSize(this->width(),this->height());

You need to change the windowFlags of the dialog and set it to Qt::MSWindowsFixedSizeDialogHint.
This only works in windows.
For more information please see this example:
http://doc.qt.digia.com/4.5/widgets-windowflags.html

On QT Creator, in the UI editor, click on the top object in the properties window, then scroll at the bottom in the Layout part. You should see the layoutSizeConstraint property.
Set the layoutSizeConstraint to SetFixedSize.

If you use QtCreator (of course you are) you can set the property HorizontalsizePolicy to fixed and Vertical Policy also to Fixed. Then you can set the maximumSize to the dimensions you want. The window will not maximise again.

In code you can do something like this,
Dialog->resize(581, 292);
QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
sizePolicy.setHorizontalStretch(0);
sizePolicy.setVerticalStretch(0);
sizePolicy.setHeightForWidth(WaterLevelEditorDialog->sizePolicy().hasHeightForWidth());
Dialog->setSizePolicy(sizePolicy);
Dialog->setMinimumSize(QSize(581, 292));
Dialog->setMaximumSize(QSize(581, 292));
Dialog->setSizeGripEnabled(false);
In QtCreator do as follows,
Select the dialog box widget
Locate the dialog box widget in Object Window
In Object Window, right click on dialog box object to popup a menu
Select "Size Constraints" -> "Set Maximum Size" from the menu
Right click again on dialog object to popup a menu
Select "Size Constraints" -> "Set Minimum Size"
In Property Window,
ensure "sizePolicy"->"Horizontal Policy" has value "Fixed"
ensure "sizePolicy"->"Vertical Policy" has value "Fixed"
ensure "sizeGripEnabled" is not checked

From the Qt documentation, setSizePolicy() method either takes zero argument or two arguments but cannot be one argument. That's why you get this compilation error. From my experiment, if you don't set the fixed size. This method has no use. The window can still be resizable.

An easier way is to set the maxium size to 0.
this->setMaxiumSize(QSize(0, 0));

In case you are designing UI in QML and launching using QDeclarativeView, try the below code.
QScopedPointer<QmlApplicationViewer> viewer(QmlApplicationViewer::create());
.
.
.
//To make the window non-resizable
viewer->setFixedSize(viewer->width(),viewer->height());
Here QmlApplicationViewer is derived from QDeclarativeView.

Related

Resizing Layout equal to MainWindow

When I run my program it will display all content properly, and when I resizing the main window, the layout along with all associated widgets remain fixed, rather than resizing with the main window. I used to increase my all widget and listWidget respect to window computer resolution size but still this not one work properly.
I used this one code finding the system height and width.
QWidget widget;
widget.resize(widget.width(), widget.minimumHeight());
QRect rec = QApplication::desktop()->screenGeometry();
int h = rec.height();
int w = rec.width();
// Increasing the listwidget size
ui->listWidget->setFixedHeight(h);
ui->listWidget->setFixedWidth(w);
//increasing the button size
ui->pushButton->setFixedHeight(h0.2);
ui->pushButton->setFixedWidth(w0.2);
At this link you will find two screenshots that illustrate my problem.
Please resolve to solve my problem. Thanks very much in advance.
When defining the layout of your windows and forms in Qt Designer you have to define each element of your form in advance, in order to have a working layout.
This solution is based on the screenshots provided in the comments to the question. Follow these steps:
Add an empty widget to the central area of your form, if there is nothing there. It will be used as a placeholder for the controls you will add later, and of course you can replace it with whatever widget you want. But you need it there to define a proper layout.
In the property panel, set the horizontal QSizePolicy of this widget to MinimumExpanding.
Add an horizontal spacer to the left side of your progress bar.
Define a minimum/maximum width for the white widget on the left (I guess it's a text area). As an example set the maximum width to 200
pixels.
Make the same for the QTabWidget on the right.
Give a minimum height to the Groupbox on top.
Then give the grid layout to the MainWindow.
You should get something similar in the designer view (I use a dark theme, yours will have different colors of course):
If you complete all steps you should have a nicely resizing window.
For the future: remember to integrally define your layouts, also using placeholder widgets when needed, read carefully the documentation about the widgets size policies (there are several, you need to play with them to fully understand each one) and keep in mind that Qt uses a container based approach which is different, as an example from those used by the .Net framework that relies on the concept of anchors.
EDIT : to answer questions in the comments
You will need to add a layout to any widget that contains other widgets, e.g. adding controls to your groupbox will require to give it a grid, horizontal or vertical layout in order to scale nicely on resize. Again use spacers and size policies to make it look the way you want. If you need to add or remove controls, or change their positions, you may need to brake the layout, rearrange and then set it again.
You can also select groups of widgets and give them a layout e.g. vertical, than another group and set them horizontal and so on... then give a grid layout to the container widget to build a compound layout.
There are endless possibilities, you just need to practice and go through trial and error as for everything else...
You can also do it all programmatically, check the Qt widgets documentation for this. But for complex layouts I would not go that way: it's a lot of code... and you have to compile and run to test every modification.
Using the QtCreator, within the designer you can simply right-click on the parent-widget and add a Grid-Layout.
This one resizes it's children to it's dimensions.

Modeless Qt window on top of parent, but not on top of other applications

I wish to have a Qt dialog window that:
always stays on top of its parent (the main application window),
allows the user to interact with the parent window, and
does not always stay on top of other applications.
I've been able to achieve 1 and 3 by making the dialog modal, and I can achieve 1 and 2 by using the Qt::WindowStaysOnTopHint window flag. But I cannot manage to make all three work - is it possible?
In case answers are OS-specific, I mainly work on a Mac, but I would prefer a solution that also applies to Windows and Linux. Thanks!
You could try to use QGuiApplication::applicationStateChanged. This way you get notified if the user enters or leaves your application. Just dynamically add and remove the Qt::WindowStaysOnTopHint flag for your window. If you have multiple windows, you can use QGuiApplication::focusWindowChanged together with the first one.
Edit: To make the dialog non-modal, either set NULL as it's parent, or set the windowModality-Property to Qt::NonModal and show the dialog using show and not open or exec
Example code in a subclass of QDialog:
connect(QApplication::instance(), SIGNAL(applicationStateChanged(Qt::ApplicationState)), this, SLOT(changeAlwaysOnTop(Qt::ApplicationState)));
...
void MyDialog::changeAlwaysOnTop(Qt::ApplicationState state)
{
if (state == Qt::ApplicationActive)
setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
else
setWindowFlags(windowFlags() & ~Qt::WindowStaysOnTopHint);
show();
}
The default QWidget is enough for your needs.
If you create QWidget with parent to your mainwindow it will be on top of other widgets. You just have to create it last or stack it properly with QWidget::raise().
I know I already posted an answere, but I found the best solution:
Use QDockWidget. A DockWidget will always stay on top of it's parent, and if you set the allowedAreas property to Qt::NoDockWidgetArea, the window will behave the way you need it!
QMessageBox Inherits QDialog, the following code statify all requirements
msgBox = new QMessageBox(QApplication::activeWindow());
msgBox->setModal(false);
msgBox->setWindowFlags(msgBox->windowFlags() | Qt::WindowStaysOnTopHint);
msgBox->show()
This window will be always on top:
self.setWindowFlags(QtCore.Qt.Dialog | QtCore.Qt.WindowStaysOnTopHint)
Or you can pass your existing flags:
self.setWindowFlags( self.windowFlags() | QtCore.Qt.WindowStaysOnTopHint)
I can reproduce the original problem only if the QDialog is created with a NULL parent. Otherwise the following lines are sufficient to accomodate requirement 1, 2 and 3.
dlg=new MyDialog(applicationMainWidget);
dlg->show();

Resize QDialog at a runtime

I have a QDialog subclass containing some options of my application. Some of the options are core, the other are advanced, so I decided to put them into separeted checkable QGroupBox.
I want my dialog to shrink verticaly when the user checked off advanced options box, but I can't find the way to do it properly - the dialog size stays exactle the same
I set dialog's size policy to Expanding, tried to call adjustSize() and tried to call resize() method - nothing helps. I can't resize programmaticaly dialog to be smaller then it's current size (it only can become larger). At the same time, it is possible to resize it manualy.
Can anybody help me?
If you don't need manual resize, you can add
layout()->setSizeConstraint(QLayout::SetFixedSize);
to the dialog constructor, then the layout takes over the responsibility to automatically resize when widgets are shown or hidden.

How do you make Interface Builder respect a custom view's intrinsic content size in constraint based layout?

Interface Builder in XCode 4.5 respects the intrinsicContentSize for some views, e.g. NSButton, but I can't convince it to respect it on my own custom subviews. This causes IB to add extra constraints trying to force the layout drawn in IB, which then causes the intrinsic sizes to not be used when the program is run.
For example, consider a button centered in a window, and a custom view centered in a window…
You can see that the custom view gets four constraints, presumably because IB doesn't know the view's intrinsicContentSize. You can change which extra constraints are added, e.g. you can force it to be width and height instead, but you can't delete them.
I'm coping with this now by searching and deleting the extra constraints in my awakeFromNib, but there must be a better way to do this.
Set a placeholder intrinsic content size — a "guess," if you will — in Interface Builder.
Select your custom view.
Show the size inspector (⌘Shift5).
Change the "Intrinsic Size" drop-down from "Default (System Defined)" to "Placeholder."
Enter reasonable guesses at your view's runtime width and height.
These constraints are removed at compile-time, meaning they will have no effect on your running app, and the layout engine will add constraints as appropriate at runtime to respect your view's intrinsicContentSize.
How to actually do this, 2019
import UIKit
#IBDesignable class TagPerson: ShadowRoundedImageView {
override var intrinsicContentSize: CGSize {
var s = super.intrinsicContentSize
s.height = 40
s.width = 40
return s
}
override func prepareForInterfaceBuilder() {
invalidateIntrinsicContentSize()
}
}
However, there is a problem. Xcode is buggy. You can sometimes reset it by:
The above will of course work flawlessly at runtime. But it randomly fails to work in interface builder (even with 11+).
To make it cycle, try
The usual 'Refresh all views'
Attach and delete a pointless constraint to one of your intrinsic size views. (I've noticed if you have a number of them, doing this to one is usually enough to make Xcode cycle, then they all work.)
And finally:
Xcode has an "intrinsic size placeholder" feature.
Select one or more of your intrinsic-size elements. Toggle the bizarre placeholder thing back and fore a few times. Often that makes it cycle and the view will then work correctly.
At worst, restarting Xcode with the usual clean-everything will, sometimes, get it working.
Ok, the point here is to make Xcode use the intrinsicContentSize of your custom view in IB.
This can be achieved by adding a placeholder view inside your custom view in IB with a fixed width and height (you can center it horizontally and vertically as well)
Then select your custom view and tap "Size To Fit Content" form the Edit Menu in IB.
At this point all extra size defining constraints will be deletable leaving only positioning ones.
That way IB will size your custom view to fit the placeholder view and and Autolayout would depend on your view's override of - (CGSize)intrinsicContentSize in run time to determine your custom view's size.
Last step is to delete the placeholder view to allow your view to display its content and size correctly:
- (void)viewDidLoad
{
[super viewDidLoad];
[_placeholderView removeFromSuperview];
}
I know this is a hack but hopefully it helps you.

How do I auto-adjust the size of a QDialog depending on the text length of one of its children?

I have a QDialog I'm working with. It is made somewhat like a QMessageBox. I noticed that the size of the QMessageBox (and the size of its label) depends on the size of the message displayed.
How would I make the size of my QDialog adjust automatically like a QMessageBox? Presently my QDialog contains a button box and a label, and the QDialog is layout Vertical.
(I know I could just use the message box directly but eventually I will have more complex dialogs.)
Automatic solution:
Use layouts and set size policies to QSizePolicy::Expanding. In QtDesigner, once all your children are placed on your QDialog, then click on the Adjust Size button next layout ones. Your QDialog will be automatically resized at runtime.
Manual solution:
The QWidget class has a method adjustSize that resize the QWidget to fit its content. Just call it when all children are set.
Set your dialog to be expanding, and very small. Then, be sure to set your message before showing the dialog. When shown, it will try to find its proper size, based on the size of the objects it contains. (This happens recursively, so if the dialog isn't the direct parent of the label in which you show your message, make sure everything between the label and the dialog is set to use layouts.)
A TIP : if you try to use "adjustSize()" function when dialog is hidden, it may not be works fine. It would be better to use it after the "show()" function.

Resources