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: 300

        TableViewColumn {
            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.2

    Rectangle {
    width: 800
    height: 480
    ListModel {
    id: fruitModel
    ListElement { name: "Apple" }
    ListElement { name: "Orange" }
    ListElement { name: "Banana" }
    }
    TableView {
    id:tableview
    anchors.fill: parent

        model: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.2

    Rectangle {
    width: 800
    height: 480
    ListModel {
    id: fruitModel
    ListElement { name: "Apple" }
    ListElement { name: "Orange" }
    ListElement { name: "Banana" }
    }
    TableView {
    id:tableview
    anchors.fill: parent

        model: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
                   }
               }@

Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.