QML TreeView - Change position of expand icon - qt

I'm currently trying to change the layout of a QML TreeView so that the expand icon (the arrow or triangle you have to click in order to show or hide the children elements).
I tried anchoring the icon to the right of the TreeView, but for some reason it's not working, it remains on the left despite everything. Do you have any hint?
Thanks a lot!
TreeView {
id: treeView
anchors.fill: parent
model: treeModResult
style: TreeViewStyle {
branchDelegate: Rectangle {
width: 15; height: 15
color: "#00000000"
anchors.right: treeView.right
Image {
id: expandArrow
source: styleData.isExpanded ? "qrc:/img/icn_arrow_top.svg" : "qrc:/img/icn_arrow_bottom.svg"
sourceSize.width: parent.width
sourceSize.height: parent.height
}
ColorOverlay {
anchors.fill: expandArrow
source: expandArrow
color: "#293147"
}
}
}
}
Update
This is what I currently have:
This is what I would like to have:

I had the same issue, I came up with the following solution, as anchoring wasn't working for me neither..
style: TreeViewStyle {
branchDelegate: Rectangle{
id: expandIcon
x: control.width - width
control.width represents the width of the treeview.

Related

QML: Problems with setting the size of the button in a layout

I have this app page in qml:
Image {
source: "file:///C:/Users/image.jpg"
fillMode: Image.PreserveAspectCrop
Rectangle {
width: parent.width/3
height: parent.height/3
anchors.centerIn: parent
radius: 5
ColumnLayout {
width: parent.width * 0.5
height: parent.height * 0.5
anchors.centerIn: parent
//some components here ...
Button {
//width: 100 nothing changes in the app
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
style: ButtonStyle {
background: Rectangle {
color: "blue"
radius: 15
//width: 100 nothing changes in the app
}
label: Text {
text: qsTr("Button")
color: "white"
}
}
}
}
}
}
Now I'm trying to set the size (width and height) of the button, so that depends on the size of the parent (layout), something like width: parent * 0.4. I probably tried every possible position of the width statement in the code, but when I run the app the size of the button never changes. I also tried to set the size to a specific number, not to bind it to the parent, still nothing.
So what could be the problem here? Where and how should be the button size defined so it's binded to its parent layout size?
Have you tried the suggestion from #folibis? I'm guessing this is a similar issue to the question here. In that example, elements inside of a Layout were not responding to the width and height parameters. Setting Layout.preferredWidth and Layout.preferredHeight seemed to solve the issue. Please refer to the documentation provided in that answer.
You can still bind to the parent's properties, for example
Layout.preferredWidth: parent.width * 0.4

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.

Why does anchors.fill does not work in a QML ListView's delegate's subviews, and what is a nice solution?

I encountered this:
ListView {
id: listView
model: ["Lorem","Ipsum"]
delegate: Item {
height: 20
Text {
z: 2
text: modelData
anchors.fill: parent
}
Rectangle {
z: 1
color: "red"
// this does not work:
anchors.fill: parent
// this works, but I have mixed feelings about it:
// height: 20; width: listView.width
}
}
}
So, apparently, anchors do not work in a delegate's subitem (in this case, Rectangle is not displayed at all). I would like to understand the mechanism behind this. Also, I'd like to ask what is the preferred way to deal with this situation?
Thank You!
Item has an implicitWidth and implicitHeight of zero, so making your Rectangle and Text fill it will result in them having no size as well.
There are two things wrong with your code:
The ListView has no width or height specified.
Your delegate has no width specified.
Here's one way of doing it correctly:
import QtQuick 2.0
import QtQuick.Window 2.0
Window {
width: 300
height: 300
visible: true
ListView {
id: listView
anchors.fill: parent
model: ["Lorem","Ipsum"]
delegate: Item {
width: listView.width
height: textItem.implicitHeight
Text {
id: textItem
z: 2
text: modelData
width: parent.width
}
Rectangle {
z: 1
color: "red"
anchors.fill: parent
}
}
}
}
The documentation of ListView has more information.

How do I put an image on items of ListView and change it dynamically?

I'm trying to make a color picker in QML. The color details are stored in a ListModel and I've tried to create a horizontal row of colors to choose from.
Something like this:
The problem is, I'm unable to add a button image over the selected cell. I want to highlight the cell the user has selected by placing an image at the center of that cell.
The following is the code snippet I've written
ListView{
id: list
height: 30
width: 500
anchors.bottom: main.bottom
anchors.horizontalCenter: main.horizontalCenter
anchors.bottomMargin: 40
orientation: ListView.Horizontal
model: myModel
delegate:
Item {
id: cell
property alias cellColor: rectangle.color
signal clicked(color cellColor)
width: 500/myModel.count; height: 25
Rectangle {
id: rectangle
color: clr
anchors.fill: parent
}
onClicked:{
dynamicRect.color=cellColor
list.currentIndex=index
console.log(list.currentIndex)
}
MouseArea {
anchors.fill: parent
z: 1
onClicked: {
cell.clicked(cell.cellColor)
}
}
}
highlight:
Image {
id: button
height: 20
width: 20
source: "button.png"
anchors.horizontalCenter: list.currentItem.horizontalCenter
}
}
Any help will be highly appreciated.
Thanks!

Share equally the horizontal space in a QML Row

I need to share equally the horizontal space between all "buttons" in my Row.
I use this code with a Repeater.
Component {
id: buttonComponent
Rectangle {
height: buttonRow.height
width: buttonRow.width / buttonsRepeater.count
color: "#FFDDDD"
Text {
anchors.centerIn: parent
text: model.text
}
}
}
Rectangle {
color: "#DDDDDD"
id: buttonBar
height: 30
anchors {
bottom: parent.bottom
left: parent.left
right: parent.right
}
Row {
id: buttonRow
anchors.fill: parent
Repeater {
id: buttonsRepeater
model: buttonsModel
delegate: buttonComponent
}
}
}
Now, I like to compute the ideal width of the Row such that all my button texts appear correctly.
How can I get this ideal width?
If you don't want to use QtQuick.Layouts as they are not really ready yet, you can use this :
Rectangle {
id: buttonBar;
color: "#DDDDDD";
height: 30;
width: (buttonColumn.width + 20 + buttonRow.spacing) * buttonsRepeater.count;
anchors {
bottom: parent.bottom;
left: parent.left;
}
Column {
id: buttonColumn;
visible: false;
Repeater {
model: buttonsModel;
delegate: Text {
text: model.text;
}
}
}
Row {
id: buttonRow;
anchors.fill: parent;
property real itemWidth : ((width + spacing) / buttonsRepeater.count) - spacing;
Repeater {
id: buttonsRepeater;
model: buttonsModel;
delegate: Component {
id: buttonDelegate;
Rectangle {
height: parent.height;
width: parent.itemWidth;
color: "#FFDDDD";
border.width: 1;
Text {
anchors.centerIn: parent;
text: model.text;
}
}
}
}
}
}
I just used a hidden Column to easily compute max width of Text elements, and added a little padding in the bar width to avoid unspaced text.
The minimum width of a button itself is the implicitWidth property of its Text element.
One solution to your problem might be to add code in the Component.onCompleted handler, i.e. code that is executed after the repeater has created its items, and then sum up these implicitWidth properties of each of the repeater's item (which you can get by using its itemAt(index) function).
These kinds of dynamic layout is a bit cumbersome in QML still, which will get much better in Qt 5.1 with the introduction of Qt Quick Layouts

Resources