Extra space at the bottom of Flow - qt

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
}
}
}

Related

How can I make my GroupBox Layouts scalable in QML?

I have the following problem. I created a Periodic table in QML that consists of GroupBoxes that contain a ColumnLayout in order to arrange the specific properties of each element. But as you can see in the pictures...
Window after starting
Window after downsizing
... the properties will not scale properly according to the size of the GroupBox. So when I scale down the size of the window, some text properties will just move out of its GroupBox and lay wherever they are not supposed to be. How can I fix this?
//PeriodicTable.qml
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15
import QtQuick.Controls.Material 2.15
import QtQuick.Layouts 1.15
Item {
id: root
Button {
id: button
checkable: true
text: qsTr("Show")
onClicked: window.show()
}
Window {
id: window
Material.accent: parent.Material.accent
Material.background: parent.Material.background
Material.foreground: parent.Material.foreground
Material.primary: parent.Material.primary
Material.theme: parent.Material.theme
color: Material.background
height: parent.height
title: qsTr("Periodic table")
width: parent.width
GridView {
id: gridview
anchors.fill: parent
cellHeight: cellWidth * 1.5
cellWidth: parent.width / 18
delegate: PeriodicTableDelegate {
}
model: PeriodicTableModel {
}
}
}
}
//PeriodicTableModel.qml
import QtQuick 2.15
import QtQuick.Controls 2.15
ListModel {
id: elements
ListElement {
atomicWeight: "1.00794"
electronConfiguration: qsTr("1s")
elementName: qsTr("Hydrogen")
elementSign: qsTr("H")
ionizationEnergy: qsTr("13 5984")
ordinalNumber: qsTr("1")
unknownNumber: qsTr("S1/2")
}
} // I shortened this to just one element because yet it is the only one I have
// PeriodicTableDelegate.qml
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
GroupBox {
property int cellHeight: GridView.view.cellHeight
property int cellWidth: GridView.view.cellWidth
height: cellHeight
width: cellWidth
ColumnLayout {
RowLayout {
Label {
Layout.alignment: Qt.AlignLeft
Layout.fillWidth: true
font.bold: true
text: ordinalNumber
}
Label {
Layout.alignment: Qt.AlignRight
text: unknownNumber
}
}
Label {
Layout.alignment: Qt.AlignHCenter
font.bold: true
text: elementSign
}
Label {
Layout.alignment: Qt.AlignHCenter
text: elementName
}
Label {
Layout.alignment: Qt.AlignHCenter
text: atomicWeight
}
Label {
Layout.alignment: Qt.AlignHCenter
text: electronConfiguration
}
Label {
Layout.alignment: Qt.AlignHCenter
text: ionizationEnergy
}
}
}
a slightly contrived example:
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Layouts 1.0
Window {
height: 800
width: 600
visible: true
title: qsTr("cell test")
GridView {
id: grid
anchors.fill: parent
cellHeight: grid.height / 3
cellWidth: grid.width / 4
model: 12
delegate: Rectangle {
id: rect
width: grid.cellWidth
height: grid.cellHeight
color: Qt.rgba(Math.random(), Math.random(), Math.random(), 1)
ColumnLayout {
id: layout
anchors.fill: parent
Repeater {
model: 5
Text {
id: txt
property int fsize: (layout.height + layout.width) / 30
Layout.fillWidth: true
text: "some text"
horizontalAlignment:Text.AlignHCenter
font.pointSize: fsize > 0 ? fsize : 16
}
}
}
}
}
}
The ColumnLayout in your GroupBox is missing an anchors.fill: parent.

How to achieve click an area outside the TextField to make the TextField lose focus?

import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
TextField {
id:textField
width: 130
height: 50
}
Button {
anchors.right: parent.right
text: "lose Focus"
}
}
why textField don't lose Focus when Button Click?
How to achieve click an area outside the TextField to make the TextField lose focus?
The simplest way using your existing code is to force active focus on another item when the button is clicked:
Button {
anchors.right: parent.right
text: "lose Focus"
onClicked: forceActiveFocus()
}
To make the TextField lose focus when clicking the area outside of it, you can do something similar with MouseArea:
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
MouseArea {
anchors.fill: parent
onClicked: forceActiveFocus()
}
TextField {
id: textField
width: 130
height: 50
}
}
This item needs to be below (i.e have a lower Z value than) other items in the scene. You can also make it a parent of the other items to achieve this:
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
MouseArea {
anchors.fill: parent
onClicked: forceActiveFocus()
TextField {
id: textField
width: 130
height: 50
}
}
}
If you're using Qt Quick Controls 2, you can use the focusPolicy property on e.g. Pane:
import QtQuick 2.7
import QtQuick.Controls 2.0
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Pane {
anchors.fill: parent
focusPolicy: Qt.ClickFocus
}
TextField {
id: textField
width: 130
height: 50
}
}

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"
}
}
}
}

Issue with toolbar layout, each tab is stacking on top of each other

I'm trying to get a tool bar working but the first 3 tab buttons keep writing on top of each other.
Each tab gets display on top of one another on the left hand side of the screen.
I would like each tab button to fill and take up its on unique space.
How do I get the toolbar to display 3 individual tabs that span horizontally across the screen at equal size?
import QtQuick 2.7
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.1
import QtQuick.Controls.Styles 1.4
import QtQuick.Controls.Material 2.1
import QtGraphicalEffects 1.0
import "../controls" as Controls
Page{
anchors.fill: parent
header: ToolBar{
Material.background: "green"
TabButton {
id: tab1
width: parent.width/3
text: qsTr("Asset")
Image{
source: "../assets/clipboard.png"
}
onClicked: qmlfile1 = "./asset.qml"
}
TabButton {
id:tab2
width: parent.width/3
text: qsTr("Issue")
Image{
source: "../assets/wrench.png"
}
onClicked: qmlfile1 = "./issue.qml"
}
TabButton {
width: parent.width/3
id: tab3
text: qsTr("Log")
Image{
source: "../assets/cogs.png"
}
onClicked: qmlfile1 = "./log.qml"
}
}
Rectangle{
id: loader1
Loader{
width: pageApp.width
source: qmlfile1
}
Component.onCompleted: {
console.log(loader1.height)
console.log(pageApp.height)
console.log(tabBarApp.height)
}
}
}
The solution was to add row layout and each tab button gets
Layout.fillHeight: true
Layout.fillWidth: true
which fills the tabs out to occupy all space it needs
import QtQuick 2.7
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.1
import QtQuick.Controls.Styles 1.4
import QtQuick.Controls.Material 2.1
import QtGraphicalEffects 1.0
import "../controls" as Controls
Page{
anchors.fill: parent
header: ToolBar{
Material.background: "green"
RowLayout {
anchors.fill: parent
TabButton {
id: tab1
width: parent.width/3
text: qsTr("Asset")
Layout.fillHeight: true
Layout.fillWidth: true
Image{
source: "../assets/clipboard.png"
Layout.alignment: Qt.AlignLeft
}
onClicked: qmlfile1 = "./asset.qml"
}
TabButton {
id:tab2
width: parent.width/3
Layout.fillHeight: true
Layout.fillWidth: true
text: qsTr("Issue")
Image{
source: "../assets/wrench.png"
Layout.alignment: Qt.AlignLeft
}
onClicked: qmlfile1 = "./issue.qml"
}
TabButton {
width: parent.width/3
Layout.fillHeight: true
Layout.fillWidth: true
id: tab3
text: qsTr("Log")
Image{
source: "../assets/cogs.png"
Layout.alignment: Qt.AlignLeft
}
onClicked: qmlfile1 = "./log.qml"
}
}
}
// Add a Loader to load different samples.
// The sample Qml files can be found in the Samples folder
Rectangle{
id: loader1
Loader{
width: pageApp.width
source: qmlfile1
}
Component.onCompleted: {
console.log(loader1.height)
console.log(pageApp.height)
console.log(tabBarApp.height)
}
}
}

How visual objects fit in the screen in QML?

This is my QML code:
import QtQuick 2.10
import QtQuick.Window 2.10
import QtQuick.Layouts 1.3
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
GridLayout {
anchors.centerIn: parent
anchors.margins: 8
rowSpacing: 5
columnSpacing: 5
columns: 4
Repeater {
model: 12
Rectangle {
width: 100 / Screen.devicePixelRatio
height: 100 / Screen.devicePixelRatio
color: 'blue'
Text { anchors.centerIn: parent; text: index + 1; color: 'white' }
}
}
}
}
If I set model of Repeater is 12, the view is good like this:
But if I set model of Repeater is 36+ I get this view:
I want all rectangles to be sized and aligned according to the screen / window size. I want any rectangle doesn't overflow invisible space.
How can I do it?
f you want it to occupy all the vertical space available then you must make a calculation of the height of each rectangle:
import QtQuick 2.10
import QtQuick.Window 2.10
import QtQuick.Layouts 1.3
Window {
id: win
visible: true
width: 640
height: 480
title: qsTr("Hello World")
GridLayout {
id: gl
anchors.centerIn: parent
anchors.margins: 8
rowSpacing: 5
columnSpacing: 5
columns: 4
readonly property real heighItem : {
var rowCountEffective = Math.round(repeater.count/gl.columns)
var heightEffective = win.height-rowCountEffective*gl.rowSpacing - gl.anchors.topMargin -gl.anchors.bottomMargin
return heightEffective/(rowCountEffective * Screen.devicePixelRatio)
}
Repeater {
id: repeater
model: 50
Rectangle {
width: 100 / Screen.devicePixelRatio
height: gl.heighItem
color: 'blue'
Text { anchors.centerIn: parent; text: index+1; color: 'white' }
}
}
}
}

Resources