QML ColumnLayout does not respect minimumHeight - qt

I always have problems with the layout management of QML. So, I created a very simple QML App to check ColumnLayout. If I shrink the window horizontally, it will stop at the minimumWitdh when 100 is reached.
But if I shrink the window vertically I can shrink the window, so that both rectangles disappear.
What is going wrong? Why is the minimumHeight not respected?
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Layouts 1.15
Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World")
ColumnLayout {
Rectangle {
color: "red"
Layout.minimumWidth: 100
Layout.minimumHeight: 100
}
Rectangle {
color: "blue"
Layout.minimumWidth: 100
Layout.minimumHeight: 100
}
}
}

folbis is probably right. But I found another solution. It seems the minimumWidth and minimumHeight will calculate an implicitWidth and implicitHeight of the ColumnLayout. So, this in turn can be used as minimumWidth and minimumHeight of the window, like so:
Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World")
minimumHeight: col.implicitHeight
minimumWidth: col.implicitWidth
ColumnLayout {
id: col
Rectangle {
color: "red"
Layout.minimumWidth: 100
Layout.minimumHeight: 100
}
Rectangle {
color: "blue"
Layout.minimumWidth: 100
Layout.minimumHeight: 100
}
}
}
This is very weird, when you come from the XAML-world.

Related

Extra space at the bottom of Flow

I have a QML code like this:
MyItem.qml:
import QtQuick 2.12
import QtQuick.Controls 2.5
import QtQuick.Layouts 1.3
Item {
id: root
width: parent.width
height: grid.height
Rectangle {
anchors.fill: root
color: "blue"
z: -1
}
Flow {
id: grid
width: parent.width
spacing: 5
Button {
text: qsTr("Button 1")
}
Button {
text: qsTr("Button 2")
}
Button {
text: qsTr("Button 3")
}
}
}
main.qml:
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.5
import QtQuick.Layouts 1.3
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
ColumnLayout {
anchors.fill: parent
Button {
Layout.fillWidth: true
Layout.fillHeight: true
text: "hello"
}
MyItem {
Layout.fillWidth: true
}
}
}
If the Flow is wide enough for all three buttons to be at the same line (as with RowLayout) there is an extra empty space at the bottom of the Flow (approximately Button.height * 2). Looks like the Flow height is always calculated as the sum of all its element heights.
What is the logic behind this behavior? How to make the Flow fit its content height?
EDIT1: It is not Flow, but 'root' item has the wrong height.
EDIT2: Download the sample app
The problem with your code is that the root element the expressions:
anchors.fill: parent
height: grid.height
are competing, in the first expression you indicate that the dimensions of the root will take the size of the window and this implies the height but in the next expression you are indicating that the height will no longer be from the window but from the grid, so that generates an indefinite behavior. The only solution is to establish that the width of the root item is that of the window.
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Item {
id: root
height: grid.height
width: parent.width
Rectangle {
anchors.fill: root
color: "blue"
}
Flow {
id: grid
width: parent.width
spacing: 5
Button {
text: qsTr("Button 1")
}
Button {
text: qsTr("Button 2")
}
Button {
text: qsTr("Button 3")
}
}
}
}
Update:
It seems that you do not know how they work (read https://doc.qt.io/qt-5/qml-qtquick-layouts-layout.html#details), by default the height that is taken is the implicitHeight.
Also if you use layout you should not set anchors in the items that are directly affected by the layouts, in your case the CommandsTab is affected by the Layout so you should not use width: parent.width, is unnecesary.
CommandsTab.qml
import QtQuick 2.12
import QtQuick.Controls 2.5
import QtQuick.Layouts 1.3
Item {
id: root
implicitHeight: grid.height
Rectangle {
anchors.fill: root
color: "blue"
z: -1
}
Flow {
id: grid
width: parent.width
spacing: 5
Button {
text: qsTr("Button 1")
}
Button {
text: qsTr("Button 2")
}
Button {
text: qsTr("Button 3")
}
}
}
main.qml
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.5
import QtQuick.Layouts 1.3
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
ColumnLayout {
anchors.fill: parent
Button {
Layout.fillWidth: true
Layout.fillHeight: true
text: "hello"
}
CommandsTab {
Layout.fillWidth: true
}
}
}

Autosizing the pixel size of text based on text length or size in qml using fontSizeMode

I am trying to use fontSizeMode in qml in order to fix big text in rectangle.
import QtQuick 2.9
import QtQuick.Window 2.2
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Rectangle
{
color: "Red"
height:50
width:50
Text { text: "Hello"; fontSizeMode: Text.Fit; minimumPixelSize: 5; font.pixelSize: 50 }
}
}
My aim is to shrink text size if text is bigger than rectangle and a minimum pixel size is given as shown in program. But text is not shrinking. How can I solve this problem?
got the answer I should use width:parent.width height:parent.height to make it work
working code:
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Rectangle
{
color: "Red"
height:50
width:50
Text {
width:parent.width
height:parent.height
text: "Hello"; fontSizeMode: Text.Fit; minimumPixelSize: 5; font.pixelSize: 50 }
}

Qt ColumnLayout full screen

Qt: 5.11.1
OS: Windows 10 64bit
This is Qt Quick application. when the window is in full screen mode. The layout becomes strange. I think it's an afterimage of the previous size.
startup
full screen
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Layouts 1.3
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
ColumnLayout{
spacing: 2
anchors.fill: parent
Rectangle {
Layout.alignment: Qt.AlignCenter
color: "red"
Layout.preferredWidth: 40
Layout.preferredHeight: 40
}
Rectangle {
Layout.alignment: Qt.AlignRight
color: "green"
Layout.preferredWidth: 40
Layout.preferredHeight: 70
}
Rectangle {
Layout.alignment: Qt.AlignBottom
Layout.fillHeight: true
color: "blue"
Layout.preferredWidth: 70
Layout.preferredHeight: 40
}
Rectangle {
Layout.alignment: Qt.AlignBottom
Layout.fillHeight: true
color: "orange"
Layout.preferredWidth: 70
Layout.preferredHeight: 40
}
}
}
Not an answer, but a simplification of the problem
import QtQuick 2.11
import QtQuick.Window 2.11
Window {
visible: true
width: 640
height: 480
// Works with any Item
Rectangle {
anchors.centerIn: parent
color: "red"
width: 40
height: 40
}
}
How to reproduce
On Windows 10, click on the window's maximize button
Previous frame is not cleared
Could be related to https://bugreports.qt.io/browse/QTBUG-54451
New bug created https://bugreports.qt.io/browse/QTBUG-70570

Qt Quick layout changes on different events

When I execute my QML code, the output is:
When I minimize the window, It becomes like
and finally, when I again maximize the window it changes to
the GUI which I want to make looks like
![][5]
I am not getting what is the issue for all of the changes in GUI at different events. And this is the Qml code which I wrote
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Layouts 1.3
Window {
visible: true
width: 1080
height: 720
title: qsTr("Login")
GridLayout{
Rectangle{
id:one
Rectangle
{ id:two
color:"black";
width: 700
height:40
}
Image {
id: image
x: 470
y: 0
width: 54
height: 42
source: "qrc:/user.png"
}
Rectangle
{
id:three;
color:"#f47a42";
width: 200
height:40
anchors.left:two.right;
anchors.margins:940
Text {
id: user
text: qsTr("4200")
color:"white"
anchors.top: value.bottom
}
Text
{
id: value;
text: qsTr("User");
color:"yellow"
}}
}
}
Rectangle{
ColumnLayout{
width: 50
height: childrenRect.height+fillHeight;
}
color:"green"
}
}
So why this is happening and how can I solve this problem?
Output of the code below
Here is example of scalable window:
import QtQuick 2.11
import QtQuick.Window 2.11
import QtQuick.Layouts 1.11
Window {
visible: true
width: 800
height: 600
title: qsTr("Layout example")
ColumnLayout{
spacing: 0
anchors.fill: parent
Item {
id: titlebar
Layout.preferredHeight: 40
Layout.fillWidth: true
RowLayout {
anchors.fill: parent
spacing: 0
Rectangle {
Layout.fillWidth: true
Layout.fillHeight: true
color: "orange"
Text {
anchors.centerIn: parent
text: "Title"
}
}
Rectangle {
Layout.preferredWidth: 100
Layout.fillHeight: true
color: "lightgreen"
Text {
anchors.centerIn: parent
text: "Actions"
}
}
}
}
Rectangle {
id: content
Layout.fillHeight: true
Layout.fillWidth: true
color: "lightyellow"
Text {
anchors.centerIn: parent
text: "Content"
}
}
}
}

How to make image to fill qml controls button

I want icon to fill Button. Here is code:
import QtQuick 2.3
import QtQuick.Controls 1.2
import QtQuick.Layouts 1.1
import QtQuick.Window 2.2
Window{
id: root
title: "settings"
flags: Qt.Dialog
minimumHeight: 700
minimumWidth: 700
maximumHeight: 700
maximumWidth: 700
ColumnLayout{
id: columnLayout
anchors.fill: parent
RowLayout{
Button{
iconSource: "images/1x1.png"
checkable: true
checked: true
Layout.minimumWidth: 100
Layout.minimumHeight: 100
}
Button{
iconSource: "images/1x2.png"
checkable: true
checked: false
Layout.minimumWidth: 100
Layout.minimumHeight: 100
}
Button{
iconSource: "images/2x1.png"
checkable: true
checked: false
Layout.minimumWidth: 100
Layout.minimumHeight: 100
}
Button{
iconSource: "images/2x2.png"
checkable: true
checked: false
Layout.minimumWidth: 100
Layout.minimumHeight: 100
}
}
Rectangle{
visible: true
implicitHeight: 600
implicitWidth: 700
color: "red"
}
}
}
Button size is 100*100 pixels but image size is much lower. How to make image to be as big as button
It really depends on what you want to achieve. IMO, there are three solutions here:
1) If you need an image as a button, just use Image with a MouseArea filling it:
Image {
source: "http://images5.fanpop.com/image/photos/27500000/Cool-beans-azkaban-27533920-200-200.gif"
MouseArea {
anchors.fill: parent
onClicked: {
console.info("image clicked!")
}
}
}
2) If you want to use a button with an image, redefine the label property of the style, as follows:
Button{
width: 200
height: 200
style: ButtonStyle {
label: Image {
source: "http://images5.fanpop.com/image/photos/27500000/Cool-beans-azkaban-27533920-200-200.gif"
fillMode: Image.PreserveAspectFit // ensure it fits
}
}
}
This way you can fit any image in the Button and the small padding to the borders allows you to see when the button is clicked/checked. Mind that, by using ButtonStyle, you lose the platform style.
3) If you really want to use the Button and make it look like an Image follow the smart approach proposed by Mitch.
If you don't mind using private API, there's the padding property:
import QtQuick 2.4
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2
Item {
width: 200
height: 200
Button {
iconSource: "http://www.sfweekly.com/imager/the-exhikittenist-cattown-cat-pics-and-m/b/square/3069319/58c8/WikiCat.jpg"
anchors.centerIn: parent
style: ButtonStyle {
padding {
left: 0
right: 0
top: 0
bottom: 0
}
}
Rectangle {
anchors.fill: parent
color: "black"
opacity: parent.pressed ? 0.5 : 0
}
}
}
Looking at ButtonStyle.qml:
/*! The padding between the background and the label components. */
padding {
top: 4
left: 4
right: control.menu !== null ? Math.round(TextSingleton.implicitHeight * 0.5) : 4
bottom: 4
}
If you want the image will fill the button :
Button{
Image {
anchors.fill: parent
source: "images/1x1.png"
fillMode: Image.Tile
}
checkable: true
checked: true
Layout.minimumWidth: 100
Layout.minimumHeight: 100
}
or some another fillMode, as you need
I have gone through same problem stated here. thanks a lot for different solutions. But the one that #folibis suggested finally gave a platform looked (flat in windows 10) button with my svg image. But it does work directly well. three reasons:
1. The image was tightly fit with button.To keep like an icon, I used a FLAT groupbox.
2. fillmode tile is not appropriate when we look for simple iconic image on a button. I have changed it to PreserveASpectFit.
3. checkable and checked properties were not intended for normal action buttons. But surely the question's code sample has got these.
pl see my code here. may be useful. Once again Thanks to #Folibis
Button {
id: nextButton
GroupBox {
flat: true
anchors.fill: parent
Image {
anchors.fill: parent
source: "qrc:/next.svg"
fillMode: Image.PreserveAspectFit
}
}
Layout.minimumWidth: 100
Layout.minimumHeight: 100
}

Resources