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

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
}

Related

QML: Setting a row width in a ListView

I have a page with a ListView in a layout. The ListView consists of several rows represented with Rectangles and a RowLayout in it. The RowLayout itself consists of Text elements. The problem which I'm facing is that I can't properly set the width of these Text elements. E.g. I want the first Text element to have a 1/3 width of the whole row. The way I'm setting it now makes the Text element width to be cca 3/4 of the row width, at least visually it looks like that. What would be the proper way of setting the Text element width?
Item {
ColumnLayout {
anchors.fill: parent
// some components here ...
Rectangle {
width: parent.width
Layout.fillWidth: true
Layout.fillWidth: true
Rectangle {
anchors.fill: parent
anchors.margins: 0.1 * parent.height
ListView {
id: listView
anchors.fill: parent
model: SomeModel {}
delegate: Rectangle {
height: 40
width: listView.width
RowLayout {
width: listView.width
Text {
Layout.preferredWidth: 0.3 * listView.width
text: "text1"
}
Text {
text: "text2"
}
// some other Text elements ...
}
}
}
}
}
}
}

How to set " qml TableViewColumn " height?

I'am using Qml to develop a system, I want to change TableViewColumn's default height and its border style. I just want to show the bottom/right borders, to look like table.
In your TableView you could define custom itemDelegate with borders and desired height https://doc.qt.io/qt-5/qml-qtquick-controls-tableview.html#itemDelegate-prop
TableView {
itemDelegate: Rectangle {
height: 30 // put your height here
border.color: "black"
border.width: 1
Text {
anchors.verticalCenter: parent.verticalCenter
color: styleData.textColor
elide: styleData.elideMode
text: styleData.value
}
}
}
You can use rowDelagate property of TableView component.
TableView {
id: idReadDataTableView
anchors.fill: parent
rowDelegate: Rectangle {
width: parent.width
height: 40
}
}

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
}

Error: QML Column: Cannot specify top, bottom, verticalCenter, fill or centerIn anchors for items inside Column

file:///home/biergaizi/WeCase.commit/src//ui/SmileyDelegate.qml:6:5:
QML Column: Cannot specify top, bottom, verticalCenter, fill or centerIn
anchors for items inside Column
Why I got that? I tried to comment each line without find answer.
I do not have any idea with it.
SmileyView.qml
import QtQuick 1.0
Rectangle {
width: 300; height: 200
GridView {
id: grid
anchors.fill: parent
cellWidth: 36; cellHeight: 40
model: SmileyModel
delegate: SmileyDelegate {}
highlight: Rectangle { color: "lightsteelblue"; radius: 5 }
focus: true
}
}
SmileyDelegate.qml
import QtQuick 1.0
Item {
width: grid.cellWidth; height: grid.cellHeight
Column {
anchors.fill: parent
Image { source: path; anchors.horizontalCenter: parent.horizontalCenter }
Text { text: name; anchors.horizontalCenter: parent.horizontalCenter }
MouseArea {
anchors.fill: parent
onClicked: {
highlight: color: "lightsteelblue"; radius: 5
grid.currentIndex = index
}
onDoubleClicked: {
parentWindow.returnSmileyName('[' + name + ']')
}
}
}
}
Column is trying to anchor your MouseArea to next to the Image and the Text, but the MouseArea specifies its anchor to fill its parent. Those two things are contradictory, and hence why you get the error.
You'll probably find it works as you expect if you move the MouseArea out of Column and into the base Item for SmileyDelegate.

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