QML Layout not limiting width of children - qt

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
}

Related

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
}

Set height of popup to contain contents

I want to set the size (mainly height) of my popup to fit the contents depending on how much text is shown or whether there's an icon image shown on popup. How do I set the height of popup.
Eg.
Popup {
id: popup
width: window.width/2
height: window.height/4
x: window.width/2 - width/2
y: window.height/2 - height/2
Rectangle {
id: popupContent
width: parent.width
height: parent.height
visible: notification
anchors.fill: parent
Rectangle {
id: iconField
anchors.top: parent.top
width: parent.width
height: parent.height/2
Image {
id: img
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
width: window.width/18
height: window.width/18
fillMode: Image.PreserveAspectFit
source: "qrc:/images/icons/info.png"
}
}
Rectangle {
id: textField
anchors.top: iconField.bottom
width: parent.width
height: parent.height/2
Text {
id: text1
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
horizontalAlignment: Text.AlignHCenter
width: parent.width
wrapMode: Text.WordWrap
text: "This long text overflows out of the popup up rectangle!"
}
}
}
}
If I use a long text then the text overflows from the popup rectangle. I tried using implicitHeight in different places but I don't understand how to apply it in this situation.
There's several issues with your code. It's hard to make a perfect answer because I don't know exactly what's intended. For example, your text will always be off the bottom of the Rectangle because you anchored textField's anchor.top to iconField.bottom, and iconField is the same size as the entire popup. But here's some ideas on how to improve it.
Your popupContent is a Rectangle, but I'm not sure if you actually are intending to draw a rectangle there or not. I think you could replace that with a ColumnLayout like the example here.
You can also manually specify the height of your content using the contentHeight property. You could set it to the height of your iconField plus the height of your textField, plus any padding you want.
Every Item has a property called childrenRect.height which will tell you the combined height of all of its children.
For all of these options though, you will need to stop setting every object's height to be the same as its parent's height.

How to increase height of Rectangle according to text in QML

I am not able to increase height of Rectangle (or RowLayout) wrapped around Text item that could dynamically change (chat message for example).
I tried bunch of approaches (Text.paintedHeight, childrenRect ...) but everything looks funky when text is wrapped.
My goal is display chat messages, stretch them according their wrapped text height.
Thanks for any input.
import QtQuick 2.0
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0
ApplicationWindow {
visible: true
width: 900
height: 500
ColumnLayout {
width: parent.width
spacing: 2
RowLayout {
id: rowLayout
spacing: 3
Rectangle {
height: 50
width: 50
color: "red"
}
Rectangle {
id: rectangle
width: 50
color: "green"
Layout.fillHeight: true
Layout.fillWidth: true
Text {
id: element
text: "If the GridLayout is resized, all items in the layout will be rearranged. It is similar to the widget-based QGridLayout. All visible children of the GridLayout element will belong to the layout. If you want a layout with just one row or one column, you can use the RowLayout or ColumnLayout. These offer a bit more convenient API, and improve readability.\n\nBy default items will be arranged according to the flow property. The default value of the flow property is GridLayout.LeftToRight.\n\nIf the columns property is specified, it will be treated as a maximum limit of how many columns the layout can have, before the auto-positioning wraps back to the beginning of the next row. The columns property is only used when flow is GridLayout.LeftToRight."
anchors.rightMargin: 10
anchors.leftMargin: 10
anchors.fill: parent
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignLeft
wrapMode: Text.WordWrap
clip: false
font.pixelSize: 12
}
}
}
}
}
You have to specify the implicitHeight and implicitWidth for Rectangle (and Item for that matter).
Rectangle {
id: rectangle
width: 50
color: "green"
Layout.fillHeight: true
Layout.fillWidth: true
implicitWidth: element.implicitWidth
implicitHeight: element.implicitHeight
Text {
id: element
anchors.fill: parent
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignLeft
wrapMode: Text.WordWrap
clip: false
font.pixelSize: 12
}
}
Please note that your current setup with anchors.margins is slightly conflicting here, since that is not counted in the implicitHeight/Width, so I left them out.
Another option would be to set the background for a Label (from QtQuick.Controls) to your desired Rectangle, that will then be stretched properly:
Label {
leftPadding: 10
rightPadding: 10
...
background: Rectangle {
color: "green"
}
}
In my opinion this would give you easier control about the position of your text.

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

What is the difference between Row and RowLayout?

This works as intended with Row, but not with RowLayout. Why? What is the difference between the two?
ApplicationWindow {
title: "Testing"
width: 640
height: 480
//RowLayout {
Row {
anchors.fill: parent
Rectangle {
id: rect1
width: parent.width * 0.3
height: parent.height
color: "blue"
}
Rectangle {
height: parent.height
width: parent.width * 0.7
color: "red"
}
}
}
Row is a Item Positioner. Positioner items are container items that manage the positions of items in a declarative user interface.
RowLayout is part of Qt Quick Layouts. They manage both the positions and the sizes of items on a declarative user interface, and are well suited for resizable user interfaces.
Your code with RowLayout should look like this:
RowLayout{
anchors.fill: parent
spacing: 0
Rectangle{
Layout.fillHeight: true
Layout.preferredWidth: parent.width * 0.3
color: "blue"
}
Rectangle{
Layout.fillHeight: true
Layout.fillWidth: true
color: "red"
}
}
I think
Row is a container which grows the size based on the children of Row, making them line up as a row, so the children of it shall have size.
RowLayout is the wrapper of its children, giving them the ability of row positioning and resizing based on the size of RowLayout, so RowLayout shall have its own size to help the children to position and resize.

Resources