QML dropdown list/combobox-like in tableview , z-ordering of items
-
Hi,everyone.
I want to put a combobox-like component in QML TableView. When click each item , send the currentText to some c++ function and return some data according to the currentText. QML then pop a listview with returned data.I found some methods to create a dropdown list ("method":http://qt-project.org/forums/viewthread/40907 ).
My dropdown opens to down and I need it to overlay other components in this state. And in case two dropdowns are nearby (vertically), they have to overlay each other on opening.
How to make my two or more components to overflow each other and also tableview?The view after I click the item doesn't overlay the tableview. "picture":http://i.imgur.com/i4Vru45.png
I try to use the z index but it doesn't work.
I would apreciate any help :)
Thanks in advance.@
Rectangle {
width: 800
height: 480
ListModel {
id: fruitModel
ListElement { name: "Apple" }
ListElement { name: "Orange" }
ListElement { name: "Banana" }
}
ListModel {
id: nestedModel
ListElement { categoryName: "Veggies" }
ListElement { categoryName: "Fruits" }
ListElement { categoryName: "Cars" }
}
TableView {
id:tableview
model:nestedModel
height: 300TableViewColumn { role:"categoryName" title:"categoryName" width: 300 delegate: Rectangle { id:combo width: 200; height: 100; smooth:true; Rectangle { id:chosenItem1 radius:1; width:parent.width; height:combo.height; smooth:true; Text { anchors.top: parent.top; anchors.margins: 8; id:chosenItemText1 text:styleData.value; anchors.topMargin: 1 anchors.left: parent.left anchors.leftMargin: 12 font.family: "Arial" font.pointSize: 13; smooth:true } MouseArea { width: 400 height: 30 anchors.bottomMargin: 0 anchors.fill: parent; onClicked: { combo.state = combo.state==="dropDown"?"":"dropDown" } } } Rectangle { id:dropDown width:combo.width; height:0; clip:true; radius:1; anchors.top: chosenItem1.bottom; anchors.margins: 2; color: "lightblue" ListView { id:listView1 height:500; model:fruitModel currentIndex: 0 delegate: Item{ width:combo.width; height: combo.height; z:1 //doesn't work Text { text: modelData anchors.top: parent.top; anchors.left: parent.left; anchors.margins: 5; } MouseArea { anchors.fill: parent; onClicked: { combo.state = "" chosenItemText1.text = modelData; listView1.currentIndex = index; } } } } } states: State { name: "dropDown"; PropertyChanges { target: dropDown; height:30*fruitModel.count } } transitions: Transition { NumberAnimation { target: dropDown; properties: "height"; easing.type: Easing.OutExpo; duration: 1000 } } } } }
@
-
Not sure exactly what you are trying to do but did you consider just putting a combobox in as a delegate?
@
import QtQuick 2.2
import QtQuick.Controls 1.2Rectangle {
width: 800
height: 480
ListModel {
id: fruitModel
ListElement { name: "Apple" }
ListElement { name: "Orange" }
ListElement { name: "Banana" }
}
TableView {
id:tableview
anchors.fill: parentmodel:fruitModel TableViewColumn { title: "first column" } TableViewColumn { role:"categoryName" title:"combo column" width: 100 delegate: Item { ComboBox { anchors.verticalCenter: parent.verticalCenter model: ListModel { ListElement { text: "Veggies" } ListElement { text: "Fruits" } ListElement { text: "Cars" } } } } } }
}
@ -
[quote author="Jens" date="1401280230"]Not sure exactly what you are trying to do but did you consider just putting a combobox in as a delegate?
@
import QtQuick 2.2
import QtQuick.Controls 1.2Rectangle {
width: 800
height: 480
ListModel {
id: fruitModel
ListElement { name: "Apple" }
ListElement { name: "Orange" }
ListElement { name: "Banana" }
}
TableView {
id:tableview
anchors.fill: parentmodel:fruitModel TableViewColumn { title: "first column" } TableViewColumn { role:"categoryName" title:"combo column" width: 100 delegate: Item { ComboBox { anchors.verticalCenter: parent.verticalCenter model: ListModel { ListElement { text: "Veggies" } ListElement { text: "Fruits" } ListElement { text: "Cars" } } } } } }
}
@[/quote]Hi,Jens. Thanks for your reply. But what I want is to put different data in each combobox in the same TableViewColumn.
For instance,there are two comboboxes in first column and contain data {L1,L2,L3} and {B1,B2}.It's the initial state and the data might be changed by other component.Maybe change to {A1,A2,A3} and {B1,B2}.
I have posted another post about my requirement few days ago "problem":http://qt-project.org/forums/viewthread/42956/At first I have tried QML ComboBox,but I don't know how to separe the data to each combobox. All comboboxes which in the same tableview column contain the same data {L1,L2,L3,B1,B2}.
I am not sure and don't know how the combobox can achieve my requirement. So,I try to create a dropdown list/combobox-like and I face the problem about the item z-order. I want the dropdown list overlay other components when they being clicked.Hi,Jens. I hope my problem clear to you. The code above is an example. So,the data I used is the fixed data in ListModel here , but in the future the changed data in dropdown list might from some c++ function dynamically according to their currentText.
-
A little progress to me?!
I have found this article "info":https://qt-project.org/forums/viewthread/3330
He try to let the component he want to be the toplevel(z-order) than others.
@Component.onCompleted: {
// Reparent the popup to the top-level item so that it always stays on top of all other items
var topLevel = popup
while(topLevel.parent) {
topLevel = topLevel.parent
}
var coordinates = popup.mapToItem(topLevel, 0, 0)
popup.parent = topLevel
popup.x = coordinates.x
popup.y = coordinates.y
}@So,I tried to use it and put it to my dropdown list. I modified the part of the code I provided at first.
@Rectangle {
id:dropDown
width:combo.width;
height:0;
clip:true;
radius:1;
anchors.top: chosenItem1.bottom;
anchors.margins: 2;
//color: "lightblue"
//border.color: "black"
ListView {
id:listView1
height:500;
model:fruitModel
currentIndex: 0
focus:true
delegate: Rectangle{
width:combo.width;
height: combo.height;
color: "white"
border.color: "black"
Text {
text: modelData
anchors.top: parent.top;
anchors.left: parent.left
anchors.leftMargin: 15
anchors.right: parent.right
anchors.rightMargin: 15
anchors.bottom: parent.bottom
anchors.bottomMargin: 5
font.pointSize: 13;
}
MouseArea {
anchors.fill: parent;
onClicked: {
combo.state = ""
chosenItemText1.text = modelData;
listView1.currentIndex = index;
}
}Component.onCompleted: { var topLevel = dropDown while(topLevel.parent) { topLevel = topLevel.parent } //topLevel=topLevel.parent.parent.parent var coordinates = dropDown.mapToItem(topLevel, 0, 0) dropDown.parent = topLevel dropDown.x = coordinates.x dropDown.y = coordinates.y+chosenItem1.height } } } } states: State { name: "dropDown"; PropertyChanges { target: dropDown; height:chosenItem1.height*fruitModel.count; } } transitions: Transition { NumberAnimation { target: dropDown; properties: "height"; easing.type: Easing.OutExpo; duration: 1000 } } } }@
It makes the dropdown list to overlay other component,but some other problem occur. It seems that z index works.But now the x and y index don't work.
"before click":http://i.imgur.com/aAn92Ao.png
"after click":http://i.imgur.com/bGNMEzw.png
Maybe it is because I used the mapToItem in wrong way? -
OK,I have found the problem.
I can't change the parent in Component.onCompleted.I need to change it in MouseArea's onClicked signal which I want to popup the dropdown list.@ MouseArea {
width: 400
height: 30
anchors.bottomMargin: 0
anchors.fill: parent;
hoverEnabled: true
onClicked: {
combo.state = combo.state==="dropDown"?"":"dropDown"
// Reparent the dropDown to the top-level item so that it always stays on top of all other items
var topLevel = dropDown
while(topLevel.parent) {
topLevel = topLevel.parent
}var coordinates = dropDown.mapToItem(topLevel, 0, 0) dropDown.parent = topLevel dropDown.x = coordinates.x dropDown.y = coordinates.y } }@