I have this code:
import QtQuick 2.3
import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.1
import QtQuick.Controls 1.2
Dialog {
standardButtons: StandardButton.Ok | StandardButton.Cancel
width: layout.implicitWidth
height: layout.implicitHeight
RowLayout {
id: layout
anchors.fill: parent
Item {
width: 10
height: 1
}
GridLayout {
columns: 2
rowSpacing: 10
Layout.fillHeight: true
Layout.fillWidth: true
Text {
text: "Hello world? "
}
Text {
text: "Hello world!"
}
Text {
text: "Goodbye world? "
}
Text {
text: "Goodbye world!"
}
}
Item {
width: 10
height: 1
}
}
}
When you run it it looks like this, and the dialog can be resized to any size. Also the RowLayout
actually doesn't fill its parent as you can see.
How can I make it so that the dialog can't be resized below the minimum size of the layout, and so that the layout fills the dialog?
Unfortunately this is a bug in Qt. Currently the documentation is misleading and
Dialog
does not size itself correctly to the contents. Consider this working example, which I based on theDefaultFontDialog
:This works exactly as expected, though of course you don't get the buttons.
If you just change it to a
Dialog
and uncomment thestandardButtons
, then it stops working - you can resize the dialog to clip its contents (width-wise at least), and the contents do not expand to the dialog size.The reason for the minimum width not working becomes clear when we look at the source code for
Dialog
(inqtquickcontrols/src/dialogs/DefaultDialogWrapper.qml
):minimumWidth
is hardcoded toScreen.pixelDensity * 50
!! There was never any hope that it would match the dialog contents.minimumHeight
does work better (though not perfect, I believe because the spacing isn't considered).I'm not sure why the defaultContentItem does not expand correctly, but anyway. It looks like the only solution at the moment is to use
AbstractDialog
and implement the buttons andaccepted()
/rejected()
/etc. signals yourself. Bit of a pain.Edit / Solution
I did some further investigation.
The reason the defaultContentItem doesn't expand is because it's bottom anchor isn't tied to the top of the button row:
Minimum sizes just don't work that well with anchor-based layouts. They do with GridLayout-based layouts.
Unfortunately childrenRect has no implicitWidth/Height so we have to actually have the child items go into a ColumnLayout rather than be the ColumnLayout.
...
You have to use it a bit differently to a normal
Dialog
. Just imagine it is aColumnLayout
(this is a slightly different example to the original question):By the way you could change the
ColumnLayout
to aGridLayout
and expose thecolumns
property if you want. That might make more sense.A small issue
It turns out a
QWindow
's minimum width and height only ensure that the dialog isn't actively resized to be less than its content. It doesn't ensure that the dialog is never smaller than its content, because the content can grow after the dialog is created (e.g. extra items added). To workaround this I added this function to myColumnLayoutDialog
:It has to be called manually when you change the dialog contents. Or to do it automatically you can add this to the
content
rectangle: