How to show the content in the center in qml? - qt

Hi there i am working on a mobile application using qml, it has different icon, buttons,labels,text etc. So i want my application to fit in every screen size. So i need to show these element on center of the device. I have used anchor.centerIn:parent but when i use this on second element, the first element gets override by the 2nd element. Here is my example
Page {
id:page
Rectangle{
anchors.fill: parent
color: "#8d6d89"
Label{
anchors.centerIn: parent
font.pixelSize: app.titleFontSize
font.bold: true
wrapMode: Text.Wrap
padding: 16*app.scaleFactor
text: "TESTING PAGE"
}
Button{
id:btn
height: 40*scaleFactor
width: 200*scaleFactor
text: "CLICK HERE"
anchors.centerIn: parent
anchors.topMargin: 20*app.scaleFactor
}
}
}

Instead of this:
anchors.topMargin: 20*app.scaleFactor
Try this:
anchors.verticalCenterOffset: 20*app.scaleFactor

Related

QT anchors.horizontalCenter jumps when resizing window, why?

here.
Trying a very simple test, just to display two text boxes centralized on the screen. However, when I start the application they look wrong. Then, after I re-size the window , the screen refreshes and it looks correct. Why can't it look correct at startup?
When I launch the application this is what I see (incorrect)
After I re-size the window (correct)
QML
Window {
id: mainWindowId
width: 320
height: 240
visible: true
color: "black"
title: qsTr("Test")
Row
{
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
Rectangle
{
id: mRect1
width : mText1.implicitWidth;
height : mText1.implicitHeight;
color : "cornflowerblue"
Text {
font.pointSize: 24
color: "white"
anchors.centerIn: parent
id: mText1;
text: mLastName
}
}
Rectangle
{
id: mRect2
width : mText2.implicitWidth;
height : mText2.implicitHeight;
color : "cornflowerblue"
Text {
font.pointSize: 24
color: "white"
anchors.centerIn: parent
id: mText2;
text: mFirstName
}
}
}
}

anchor.centerIn doesn't work as expected in my case

I'm creating a component in QML, works fine but I want the TEXT field to be in the center of rectangle. For that I've anchored it accordingly but the anchor doesn't work. I don't know why.
Item {
id: root
property int main_rect_height: 32
property int elem_txt_size: 14
property string elem_border_color: "red"
property int elem_width: parent.width/6.5
Rectangle {
id: clients_rect
width: root.parent.width-27
height: main_rect_height
color: "transparent"
border.color: "black"
Rectangle {
id: username_rect
width: elem_width
height: parent.height
color: "transparent"
border.color: elem_border_color
Text {
id: username_txt
text: "USERNAME"
font.pixelSize: elem_txt_size
anchors {
fill: parent
centerIn: parent // THIS DOESN'T WORK!
}
}
}
}
By using anchors.fill: parent, you're setting the size and position of the Text object to match the parent. Centering an object of the same size won't do anything because it already takes up the entire space of the parent. And by default, the text is aligned to the top and left. You have two options:
You can use Text's alignment properties to align the text within itself to be centered:
Text {
anchors.fill: parent
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
Or, you can simply use centerIn without the fill.
Text {
anchors.centerIn: parent
}

ListView dynamic anchoring

Let us suppose I have a card made using Rectangle and I want to show buttons on top of it when clicked. I'm calling showMenu() function to do that and for buttons I'm using an ListView with dynamic ListModel. The problem with such is that the button gets added bellow the Rectangle instead of the top of it. The anchor is not updating after appending an item to the model. Here is my code
Item {
width: 120
height: 120
Rectangle {
id: card
width: 50
height: 100
color: "pink"
anchors.bottom: parent.bottom
Item {
id: rec
width: 50
anchors.bottom: parent.top // This anchor is not updating after appending an item to the list.
ListModel {
id: menuListModel
}
Component {
id: delegate
Rectangle {
width: 120
height: 20
color: "blue"
Text {
anchors.fill: parent
anchors.centerIn: parent
text: commandText
}
}
}
ListView {
anchors.fill: parent
model:menuListModel
delegate: delegate
interactive: false
}
}
MouseArea {
anchors.fill: parent
onClicked: menuListModel.append({"commandText" : "Normal Summon"});
}
}
}
This is more or less a duplicate of this question. The Item needs a height. As mentioned in the answer to that question, you can add debug statements to the code when things like this happen. In this situation, you can also add a Rectangle as a child of the Item and make sure that it's visible:
Rectangle {
anchors.fill: parent
color: "transparent"
border.color: "darkorange"
}
If it's not visible, you know that the problem lies with that (parent) item.

QML Layout not limiting width of children

I have a QML ColumnLayout with a few children, and I want to limit its width, like so:
ColumnLayout {
width: 360
height: 480
ColumnLayout {
id: inner
Layout.maximumWidth: 200
Layout.fillHeight: true
Text {
text: "Welcome"
font.pixelSize: 18
}
Text {
text: "Long explanation that should wrap, but ends up overflowing layout"
wrapMode: Text.WrapAnywhere
}
}
Rectangle {
anchors.fill: inner
z: -1
border.color: "orange"
}
}
I get the result shown in the picture below.
The orange box shows the dimensions of the inner layout item, which is all right. However, the children text of the layout is not wrapped.
I can only fix that by adding
Layout.maximumWidth: parent.width
to my 'Text' items, but that's quite awkward approach. Am I doing anything wrong, or is this a Qt bug, or is it a design approach for some reason? I am using Qt 5.4.1.
The text will only wrap if an explicit width has been set
Docs
Text
{
width: parent.width
}

Stretching element to contain all children

How is it possible in QML to automatically stretch element so that all its childs fit in it? And how to specify spacing? For example, I would like to have a rectangle around a text. The rectangle should have some internal spacing.
If I write the following then the rectangle has a size of 0,0.
Rectangle {
color: "gray"
anchors.centerIn: parent;
Text {
text: "Hello"
}
}
If I try to fix it by using the Column element, as suggested in How to make QML items to grow to fit contents?, then I get a column through the whole window/parent,
Column {
anchors.centerIn: parent
Rectangle {
color: "gray"
anchors.fill: parent
}
Text {
anchors.centerIn: parent
text: "Hello"
}
}
Edit:
I have also tried to use the Flow element instead of Column, but then I got a row through the whole window/parent.
You can use the childrenRect property for this:
import QtQuick 2.0
Rectangle {
width: 320
height: 200
Rectangle {
color: "BurlyWood"
anchors.centerIn: parent
width: childrenRect.width + 20
height: childrenRect.height + 20
Text {
id: hello
x: 10
y: 10
text: "Hello"
}
Text {
anchors.left: hello.right
anchors.leftMargin: 10
anchors.top: hello.top
text: "World"
}
}
}
However, note that using childrenRect in combination with using anchors.centerIn: parent in one of the direct children yields a warning about a binding loop.
Setting the width and height manually works, but is a little ugly:
Rectangle {
color: "gray"
width: label.width+20
height: label.height+20
anchors.centerIn: parent
Text {
id: label
anchors.centerIn: parent
text: "Hello"
}
}
I don't think using chilrenRect property is sufficient (as suggested by Thorbjørn Lindeijer). It doesn't automatically take into account all various margins of the child(ren) element(s). If the latter changes, the root rectangle doesn't automatically adjust its size. I personally came with the following solution:
Rectangle {
color: "white"
implicitWidth: row.implicitWidth + extraLeft + extraRight
implicitHeight: row.implicitHeight + extraTop + extraBottom
property int extraMargin: row.anchors.margins ? row.anchors.margins : 0
property int extraTop: row.anchors.topMargin ? row.anchors.topMargin : extraMargin
property int extraBottom: row.anchors.bottomMargin ? row.anchors.bottomMargin : extraMargin
property int extraLeft: row.anchors.leftMargin ? row.anchors.leftMargin : extraMargin
property int extraRight: row.anchors.rightMargin ? row.anchors.rightMargin : extraMargin
RowLayout {
id: row
spacing: 50
anchors.fill:parent
anchors.margins: 50
anchors.leftMargin: 100
Label {
text: "hello"
}
Label {
text: "world"
}
}
}

Resources