Why is my QML GroupBox not sizing properly within a layout? - qt

I'm trying to make two group boxes appear next to each other so that each one occupies 50% of the window. However, it looks like the width of each GroupBox is somehow changed depending on the GroupBox title length.
If the GroupBox title is the same for both GroupBox's, it will be 50% of the window. If they are not the same, the GroupBox with the longer title will occupy more of the screen.
It doesn't make sense to me for this to happen, how can I fix it so the length of the title doesn't effect the size of the GroupBox in a layout?
Here's sample code to reproduce the issue...
AppGroupBox.qml
import QtQuick 2.0
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.12
GroupBox {
Layout.alignment: Qt.AlignLeft | Qt.AlignTop
spacing:0
label.x: 0
}
AppRowLayout.qml
import QtQuick 2.0
import QtQuick.Layouts 1.12
RowLayout {
Layout.alignment: Qt.AlignLeft | Qt.AlignTop
spacing: 0
}
main.qml
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
Window {
width: 640
height: 480
visible: true
AppRowLayout {
anchors.fill: parent
AppGroupBox {
title: "Short Name"
Layout.fillWidth: true
}
AppGroupBox {
title: "Much Longer Name"
Layout.fillWidth: true
}
}
}

Qt will distribute the free space relative to the Layout.preferredWidth (or implicitWidth if that isn't defined). So, a group box with a longer title will get more space by default, as its implicitWidth is larger.
The solution is to use a fixed preferredWidth for all elements in the RowLayout:
GroupBox {
...
Layout.preferredWidth: 50 // or any other fixed value.
Layout.minimumWidth: implicitWidth // OPTIONAL: may be usefull on small screens to ensure the box is not made smaller than the title width
...
}
Note on attached properties:
Layout.alignment is an attached property available on the children of a Layout (RowLayout, GridLayout or ColumnLayout). Setting it directly inside a RowLayout object is useless (except when the RowLayout itself is a child of another Layout item.

Related

QML text area, prevent resize of text area

I am trying to create a simple window in QML with a huge text area in the center and a couple of buttons at the bottom,
bellow is the code
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
Window {
id: mainWindow
width: 500
height: 300
visible: true
title: qsTr("Hello World")
flags: Qt.WindowCloseButtonHint | Qt.CustomizeWindowHint | Qt.Dialog | Qt.WindowTitleHint
ColumnLayout{
anchors.fill: parent
anchors.margins: 5
RowLayout {
Layout.alignment: Qt.AlignTop
TextArea {
text: "Hello world!"
}
}
RowLayout {
Layout.alignment: Qt.AlignBottom | Qt.AlignRight
Button {
text: "Ok"
}
Button {
text: "Cancel"
}
}
}
}
however when i press enter key multiple times enough to reach almost at the bottom of the text area, the button moves because the text area resizes, how do I prevent this?
How do I set the text area so that it doesnt resize and push the buttons out of the window, but still be responsive that if the window resize it maintains its positions like buttons will still be buttom right and text area adjusts based on anchor.
It sounds like you want your TextArea to fill the space above the buttons, but your present code is not doing this. If I add a transparent red Rectangle to fill your TextArea, you can see what is happening:
The reason for this is that, by default, the TextArea is only as large as its text (implicitHeight/implicitWidth). Instead, if you want it to fill the top area, you need to specify Layout.fillHeight and Layout.fillWidth. This also means you maybe shouldn't have to rely on Layout.Alignment. Here is your code updated with these fills specified and some alignment properties removed:
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
Window {
id: mainWindow
width: 500
height: 300
visible: true
title: qsTr("Hello World")
flags: Qt.WindowCloseButtonHint | Qt.CustomizeWindowHint | Qt.Dialog | Qt.WindowTitleHint
ColumnLayout{
anchors.fill: parent
anchors.margins: 5
RowLayout {
TextArea {
text: "Hello world!"
Layout.fillHeight: true
Layout.fillWidth: true
}
}
RowLayout {
Layout.alignment: Qt.AlignRight
Button {
text: "Ok"
}
Button {
text: "Cancel"
}
}
}
}
You can see the result if we add another transparent colored Rectangle to make it visually clear what is happening:

QML Glow Inside a RowLayout

I am using Qt 5.15 Quick 2 QML to create a row of custom buttons in a window. When I have a standalone custom button things appear to work fine, but when I put them in a RowLayout there appears to be severe clipping and artifacting issues.
A minimum reproducible example might look like:
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Layouts 1.15
import QtQuick.Controls 2.15
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
RowLayout
{
anchors.fill:parent
anchors.margins: 25
Button
{
text: "Click Me"
Layout.fillWidth: true
}
CustomButton
{
text: "That Boy Don't Glow Right"
}
Button
{
x: 100; y:100
text: "Click Me"
Layout.fillWidth: true
}
}
}
with the custom control
import QtQuick 2.0
import QtQuick.Controls 2.15
import QtGraphicalEffects 1.15
Button {
id: control
text: "Click Me"
Glow {
anchors.fill: control
radius: 64
spread: 0
samples: 128
color: "red"
source: control
visible: true
}
}
with example output:
One potential fix is to add change the Glow to
Glow {
anchors.fill: control
width: parent.width
height:parent.height
x:control.x
y:control.y
parent: control.parent
...
But this doesn't seem right. First, it's not obvious to me where parent.width and control.x and control.parent are bound from and what happens in single and multiple nesting. If a CustomButton is placed inside another control with id control, would it rebind the property? And it appears if a RowLayout is placed inside a RowLayout, then it would require parent: control.parent.parent. In my actual code there is some non-trivial positioning to allow margins for a drop shadow, too, and the CustomButton is in another container so the actual code that works is: x:control.x + parent.pad/2 and parent:control.parent.parent.parent which is, frankly, ridiculous and assumes that non-standard fields in the parent are always available.
Is there a better way? Was hoping I could keep the button's ability to glow itself.
According to the docs:
"Note: It is not supported to let the effect include itself, for instance by setting source to the effect's parent."
So it's fortunate that you were able to get your example to work at all. One way to avoid using the parent as a source is to point the Glow object at the Button's background object:
Button {
id: control
Glow {
source: control.background
}
}

QML Dialog positioning in ApplicationWindow

I am finding it impossible to position a Dialog central to my ApplicationWindow in QT 5.12
import QtQuick 2.7
import QtQuick.Controls 2.2
import QtQuick.Dialogs 1.2
ApplicationWindow {
id:mainApplicationWindow
visible: true
height: 500
width: 500
Item {
anchors.centerIn: parent
MainWindowMessageDialog{
id: messageDialog
}
}
Component.onCompleted: {
messageDialog.open()
}
}
With MainWindowMessageDialog.qml
import QtQuick 2.0
import QtQuick.Dialogs 1.2
Dialog {
title: "There seems to be a problem"
standardButtons: StandardButton.Ok
onAccepted: {
this.close()
}
}
Gives me the image below. I've tried adding a fixed z position but nothing seems to shift the Dialog downwards into the window. I've tried MainWindowMessageDialog on its own outside of an Item. Nothing seems to shift it? Am I missing something?
This turned out to be an issue of modality.
https://bugreports.qt.io/browse/QTBUG-82737?jql=text%20~%20%22MessageDialog%22
Adding
modality: Qt.ApplicationModal
Did the trick

QuickControls2 Image does not stretch to full width of parent

I have a simple QuickControls2 QML design where an image should stretch horizontally to fill the application window and maintain its aspect ratio. But when I run my program, the image doesn't scale/stretch.
Is the problem that the image is smaller than the current window size and QT doesn't upscale/increase the size of the image? Is there a setting to make QT resize the image to fill the width regardless of image size?
Can you let me know what is wrong and how I can fix it?
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
ApplicationWindow {
id: applicationWindow
visible: true
width: 640
height: 480
title: qsTr("Scroll")
ColumnLayout {
id: mainLayout
anchors.fill: parent
Image {
id: imagePane
Layout.fillWidth: true
fillMode: Image.PreserveAspectFit
source: "placeholder.jpg"
}
}
}
Try this:
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
ApplicationWindow {
id: applicationWindow
visible: true
width: 640
height: 480
title: qsTr("Scroll")
ColumnLayout {
id: mainLayout
anchors.fill: parent
Image {
id: imagePane
Layout.preferredWidth: parent.width
Layout.preferredHeight: parent.height
fillMode: Image.PreserveAspectFit
source: "placeholder.jpg"
}
}
}
Using Image.PreserveAspectFit, image is scaled uniformly to fit without cropping ,
Now since you are not filling Layout height, image can't scale beyond it's implicit height.
As your requirement is to make QT resize the image to fill the width regardless of image size means you accept to crop the image beyond the height limit, in which case you need to use:
fillMode: Image.PreserveAspectCrop

QML Applicationwindow resize stutter

I am encountering a problem that I hope is because I am bad at coding QML and not because of some fundamental bug in Qt.
Whenever I resize the application window in the horizontal direction (width change) the window doesn't resize to where I release the mouse but "snaps" back to its minimumwidth. I have managed to strip it down to the most basic requirements to reproduce the bug.
Not releasing the mousepress causes the width to dance back and forth between the minimumwidth and where the mouse is.
Removing item removes the bug
Resizing vertically (changing height) MAY sometimes crashes the application if the mouse isn't released for a long time (eg is in state of resizing)
It is practically impossible to resize because of this
main.qml
import QtQuick 2.5
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
ApplicationWindow {
id: root
visible: true
minimumHeight: 768
minimumWidth: 1024
title: qsTr("Test")
color: "#292525"
Item {
width: 0.9*parent.width
height: 0.1*parent.height
}
}
Any idea why this is happening?
You have a form of subtle binding loop. QtQuickControls' ApplicationWindow attempts to keep the size of the window's content to match that of the content inside it, called contentItem, which all children of the ApplicationWindow are (silently) reparented into, but you are making the size of your content dependent on the window that it is residing in.
So, you resize your window, which changes the size of your Item, which changes the size of the contentItem, which makes ApplicationWindow resize your window (fighting with you).
Something like this might work:
import QtQuick 2.5
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
ApplicationWindow {
id: root
visible: true
minimumHeight: 768
minimumWidth: 1024
title: qsTr("Test")
color: "#292525"
// This item will just match the Window's size...
Item {
anchors.fill: parent
// ... and here, we'll fill a part of it with a rectangle.
Rectangle {
color: "red"
width: 0.9*parent.width
height: 0.1*parent.height
}
}
}

Resources