Qt Quick layout changes on different events - qt

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

Related

How to load and display QML file

I have two QML pages main.qml and Kos.qml,
what i want is when a button in main.qml clicked it load Kos.qml in the screen.
i did try using loader, but it is not working
import QtQuick 2.5
import QtQuick.Controls 2.5
ApplicationWindow {
id: applicationWindow
width: 640
height: 480
color: "#fc4343"
title: qsTr("Tabs")
visible: true
// HALAMAN UTAMA
Page {
anchors.centerIn: parent
anchors.fill: parent
id: page
enabled: true
Loader{
id: kos
active: true
anchors.fill: parent
}
Button {
id: button
x: 198
width: 87
height: 30
text: qsTr("Search")
font.bold: true
anchors.top: borderImage.bottom
anchors.topMargin: 198
anchors.right: toolSeparator.left
anchors.rightMargin: 28
MouseArea{
anchors.fill: parent
onClicked:{
kos.source = "Kos.qml";
}
}
background: Rectangle {
id: background
color: "#ef3644"
}
contentItem: Text {
id: textItem
font: control.font
opacity: enabled ? 1.0 : 0.3
color: "white"
text: "Search"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
}
}
}
Kos.qml i use PageBackground as a background
import QtQuick 2.4
PageBackground {
id: kos
width: 640
height: 480
Text {
id: element
x: 6
y: 20
width: 24
height: 32
color: "#ffffff"
text: qsTr("<")
font.strikeout: false
styleColor: "#ffffff"
font.underline: false
font.italic: false
font.bold: true
font.pixelSize: 25
MouseArea {
id: mouseArea
anchors.rightMargin: 0
anchors.bottomMargin: 0
anchors.leftMargin: 0
anchors.topMargin: 0
anchors.fill: parent
}
}
}
did i messed up somewhere?
I tried to run your code. Since I am not aware of what your PageBackground is, I changed that to Rectangle. That works for me. Try to start from the minimal code then add your styles and functions on top of it. Try with below minimal code. Keep both main.qml & Kos.qml in the same directory and ensure both files added to qml resources.
main.qml
import QtQuick 2.9
import QtQuick.Controls 2.2
ApplicationWindow {
id: applicationWindow
width: 640
height: 480
visible: true
Text {
anchors.centerIn: parent
text: "App window"
}
Loader {
id: loaderId
anchors.fill: parent
source: ""
}
Button {
text: "click me!!"
width: parent.width
anchors.bottom: parent.bottom
onClicked: {
if(loaderId.source == "")
loaderId.source = "Kos.qml"
else
loaderId.source = ""
}
}
}
Kos.qml
import QtQuick 2.9
Rectangle {
id: kos
width: 640
height: 480
color: "grey"
Text {
anchors.centerIn: parent
text: "<b>Loaded Item</b>"
color: "white"
}
}

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

How to managment the position of the item in the ListView during the scrolling

I have the list view. When I scroll items the top element can stop any position and can be seen half height. enter image description here
But I need that after scrolling stop the top element can be seen full height.enter image description here
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.12
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Scroll")
ColumnLayout {
anchors.fill: parent
RowLayout {
id: buttonsRow
Button {
text: "Open dump file"
}
Button {
text: "Copy raw data to clipboard"
}
}
ListView {
id: listView
flickableDirection: Flickable.VerticalFlick
boundsBehavior: Flickable.StopAtBounds
model: 100
clip: true
delegate: ItemDelegate {
text: modelData
Rectangle
{
width: parent.width - 5
height: parent.height - 5
color: "green"
}
}
Layout.fillWidth: true
Layout.fillHeight: true
ScrollBar.vertical: ScrollBar {}
}
}
}
Use the snapMode property:
ListView {
snapMode: ListView.SnapToItem
// ...
}

Make child object be always on top

I was wondering either the following functionality is available in QML: I need for a child object (a text here) to always stay on top of other object, no matter the child/ parent connection. Here is a MWE:
import QtQuick 2.9
import QtQuick.Window 2.2
import QtGraphicalEffects 1.0
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Rectangle
{
id: rectMain;
anchors.centerIn: parent
width: parent.width
height: parent.height
color: "white"
Rectangle
{
id: rect1;
width: 200;
height: 200;
x: 100;
y: 100;
color: "red";
Text
{
id: theText;
text: qsTr("text");
anchors.centerIn: parent;
}
}
Rectangle
{
id: rect2;
width: 200;
height: 200;
x: 200;
y: 200;
color: "yellow";
}
}
}
It will show this window:
As you can see the "text" is covered with rec2, as it's a child of rect1, which was created prior to rect2. Is it possible for the text to be always on top of rect2 with current parent/ child connection?
This is the idea I expressed above. But I really can imagine for myself how that could be used. If you could define your real goals we will find another solution, of course.
import QtQuick 2.11
import QtQuick.Window 2.2
import QtQuick.Controls 2.2
Window {
width: 400
height: 400
visible: true
title: "Example"
Item {
z: 1
Repeater {
id: rectGenerator
property bool loaded: false
Component.onCompleted: rectGenerator.loaded = true
model: 10
delegate: Rectangle {
width: 100
height: 100
color: Qt.rgba(Math.random(),Math.random(),Math.random(),0.8)
x: Math.round(Math.random() * 300)
y: Math.round(Math.random() * 300)
Drag.active: dragArea.drag.active
MouseArea {
id: dragArea
anchors.fill: parent
drag.target: parent
}
}
}
}
Loader {
z: 2
sourceComponent: Repeater {
model: rectGenerator.model
delegate: Text {
x: rectGenerator.itemAt(index).x
y: rectGenerator.itemAt(index).y
width: 100
height: 100
text: "item " + (index + 1)
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
}
active: rectGenerator.loaded
}
}

Even width of Text and Textfield

I have a simple login form written in QML with a custom component, MediumText, and two TextFields. Unfortunately, I'm not able to properly align the elements, as shown by the following picture:
I want the labels to the left (MediumText type), as well as the TextField instances on the right, to take up the same amount of space so that they are correctly aligned. Can you suggest me an approach? Here is my current code.
MediumText.qml:
import QtQuick 2.3
Text {
clip: true
font.pixelSize: 20
font.family: "Liberation Mono"
smooth: true
font.bold: true
wrapMode: Text.WordWrap
opacity: 1
}
Login.qml:
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.1
Rectangle {
id:rootRect
anchors.centerIn: parent
Layout.preferredWidth: 480
Layout.preferredHeight: 640
ColumnLayout {
anchors.centerIn: parent
Layout.fillWidth: true
spacing: 16
Row{
Image {
id: logoimage
height: 135
fillMode: Image.PreserveAspectFit
source: "images/logo.png"
}
}
RowLayout {
anchors.left: parent.left; anchors.right: parent.right
spacing: 4
MediumText { text: "Username: ";Layout.fillWidth:true; }
TextField { id:usernameText; placeholderText: "username"; Layout.fillWidth: true;}
}
RowLayout {
anchors.left: parent.left; anchors.right: parent.right
spacing: 4
MediumText { text: "Password:";Layout.fillWidth:true }
TextField { id:passwordText; placeholderText: "password"; echoMode: TextInput.Password; Layout.fillWidth: true;}
}
RowLayout {
spacing: 16
anchors.horizontalCenter: parent.horizontalCenter
Button { text: "Login"; onClicked: {
console.log(mojoLoginLoader.visible);
mojoLoginLoader.visible=true;
passwordText.enabled=false;
usernameText.enabled=false;
//auth_controller.sayHello();
mojoRootViewHolder.source="Welcome.qml"
}
}
Button { text: "Exit"; onClicked: auth_controller.sayNay() }
}
}
CenteredLoader{visible:false; id:mojoLoginLoader}
}
One fix that works is setting the preferredWidth property of the TextField:
MediumText { text: "Username: ";Layout.fillWidth:true;Layout.preferredWidth: parent.width/2}
You can use a GridLayout instead of building a grid by means of ColumnLayout and RowLayout.
By using the GridLayout, what you want is already guaranteed by the component.
Here is a full example from which you can start:
import QtQuick 2.3
import QtQuick.Window 2.2
import QtQuick.Controls 1.2
import QtQuick.Layouts 1.1
Window {
visible: true
width: 500
height: 500
title: "Grid example"
ColumnLayout {
anchors.centerIn: parent
Layout.fillWidth: true
spacing: 16
Row{
Image {
id: logoimage
height: 135
fillMode: Image.PreserveAspectFit
source: "images/logo.png"
}
}
GridLayout {
anchors.centerIn: parent
Layout.fillWidth: true
columnSpacing: 16
rowSpacing: 4
columns: 2
MediumText { text: "Username: "; Layout.fillWidth:true; }
TextField { id:usernameText; placeholderText: "username"; Layout.fillWidth: true;}
MediumText { text: "Password:";Layout.fillWidth:true }
TextField { id:passwordText; placeholderText: "password"; echoMode: TextInput.Password; Layout.fillWidth: true;}
}
RowLayout {
spacing: 16
anchors.horizontalCenter: parent.horizontalCenter
Button { text: "Login"; onClicked: {
console.log(mojoLoginLoader.visible);
mojoLoginLoader.visible=true;
passwordText.enabled=false;
usernameText.enabled=false;
//auth_controller.sayHello();
mojoRootViewHolder.source="Welcome.qml"
}
}
Button { text: "Exit"; onClicked: auth_controller.sayNay() }
}
}
}

Resources