Let's say I have a text field and a button. I'd like to set the button's width and height to the text field's rendered height but it's not working.
import QtQuick 2.0
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.3
import QtQuick.Window 2.10
Window {
id: window
visible: true
width: 640
height: 200
color: "#f0eded"
title: qsTr("Hello World")
RowLayout {
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
TextField {
id: txtPassword
text: qsTr("Text Field")
font.pointSize: 22
}
Button {
id: btnSubmit
width: txtPassword.height
height: txtPassword.height
text: qsTr("»")
}
}
}
It looks like the button is ignoring the binding to the text field's height. My theory is that since this attribute isn't explicitly set, QML doesn't know which width/height to assign to the button.
What would be the proper way to take on the text field's actual rendered height?
If you use layout you should not use width or height, in case you want to obtain the same height you must use implicitWidth or implicitHeight, if you want the item to occupy the height of the row then you must use Layout.fillHeight: true. In the same way for the width.
import QtQuick 2.0
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.3
import QtQuick.Window 2.10
Window {
id: window
visible: true
width: 640
height: 200
color: "#f0eded"
title: qsTr("Hello World")
RowLayout {
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
TextField {
id: txtPassword
text: qsTr("Text Field")
font.pointSize: 22
}
Button {
id: btnSubmit
implicitHeight: txtPassword.implicitHeight // or Layout.fillHeight: true
implicitWidth: implicitHeight
text: qsTr("»")
}
}
}
Or instead of using RowLayout you could use a Row:
import QtQuick 2.0
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.3
import QtQuick.Window 2.10
Window {
id: window
visible: true
width: 640
height: 200
color: "#f0eded"
title: qsTr("Hello World")
Row {
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
spacing: 5
TextField {
id: txtPassword
text: qsTr("Text Field")
font.pointSize: 22
}
Button {
id: btnSubmit
width: txtPassword.height
height: txtPassword.height
text: qsTr("»")
}
}
}
Related
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.
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
}
}
}
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
}
}
How to center element inside qml ColumnLayout? I unsuccessfully tried:
Layout.alignment: Qt.AlignCenter
code:
import QtQuick 2.6
import QtQuick.Window 2.2
import QtQuick.Layouts 1.11
import QtQuick.Controls 1.4
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
ColumnLayout{
anchors.centerIn: parent
width: parent.width
Layout.preferredHeight: parent.height
visible: true
Text{
id: myText
text: "My Text"
Layout.preferredWidth: parent.width
Layout.preferredHeight: 25
Layout.alignment: Qt.AlignCenter
}
}
}
But myText is still not horizontally centered. Any idea?
If we review with the Quick Designer we obtain the following:
As we see the item is centered. The problem is that Layout does not handle the position of the text inside the Text item, for this you must use horizontalAlignment:
import QtQuick 2.6
import QtQuick.Window 2.2
import QtQuick.Layouts 1.11
import QtQuick.Controls 1.4
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
ColumnLayout{
anchors.centerIn: parent
width: parent.width
Layout.preferredHeight: parent.height
visible: true
Text{
id: myText
text: "My Text"
Layout.preferredWidth: parent.width
Layout.preferredHeight: 25
horizontalAlignment: Text.AlignHCenter
}
}
}
This is my Box.qml
I want to use this Box as customized QML Component.
import QtQuick 2.5
Rectangle{
id: sample
width: 100
height: 35
border.color: "Black"
color: "#778899"
Text{
font.pointSize: 10
font.bold: true
anchors.centerIn: parent
}
}
This is my main.qml
import QtQuick 2.5
import QtQuick.Window 2.2
Window {
visible: true
width: 640
height: 480
title: qsTr("Repeater")
Box{
text: "Number"
}
}
But this is not working
I am getting Following Error
qrc:/main.qml:11 Cannot assign to non-existent property "text"
You have to expose that property through property.
Box.qml
import QtQuick 2.5
Rectangle{
property string mytext
id: sample
width: 100
height: 35
border.color: "Black"
color: "#778899"
Text {
font.pointSize: 10
font.bold: true
anchors.centerIn: parent
text: mytext
}
}
main.qml
import QtQuick 2.5
import QtQuick.Window 2.2
Window {
visible: true
width: 640
height: 480
title: qsTr("Repeater")
Box{
mytext: "Number"
}
}
Or use alias:
Box.qml
import QtQuick 2.5
Rectangle{
property alias text: txt.text
id: sample
width: 100
height: 35
border.color: "Black"
color: "#778899"
Text {
id: txt
font.pointSize: 10
font.bold: true
anchors.centerIn: parent
}
}
main.qml
import QtQuick 2.5
import QtQuick.Window 2.2
Window {
visible: true
width: 640
height: 480
title: qsTr("Repeater")
Box{
text: "Number"
}
}