QML - Combobox



  • Is it possible to construct a combo box using QML? Thank you! :)



  • Use Text input and ListView. When user types, show filtered ListView.



  • If you are afraid what will happen if the list falls outside of the QML area, then perhaps "this post":http://labs.qt.nokia.com/2011/08/26/toplevel-windows-and-menus-with-qt-quick/ is of interest to you.



  • I'm trying to create a combobox myself. It is somehow working, the biggest problem was to cover items which are bellow the combobox when it gets expanded.

    Check this out:

    Main.qml
    @import QtQuick 1.0

    Rectangle {

    id: main
    width: 200
    height: 300
    anchors.fill: parent
    color: "#343434"
    
    
    ListModel {
        id: model
    
        ListElement {
            value: 1
        }
    
        ListElement {
            value: 2
        }
    
        ListElement {
            value: 3
        }
    
        ListElement {
            value: 4
        }
    
        ListElement {
            value: 5
        }
    }
    
    Rectangle {
        id: comboBoxContainer            
        anchors.top: parent.top
        anchors.left: parent.left
        anchors.leftMargin: parent.width/4
        anchors.topMargin: parent.height/6
        width: parent.width/2
        height: parent.height/6
        color: "#343434"
        z: 1
    
        ComboBox {
            id: comboBox            
            anchors.top: parent.top
            anchors.left: parent.left
            width: main.width/2
            height: main.height/6
            initialText: "1"
            maxHeight: main.height/2
            listModel: model
    
            onExpanded: {
                comboBoxContainer.height = main.height/3*2
            }    
    
            onClosed: {
                comboBoxContainer.height = main.height/6
            }    
        }        
    }
    
    Text {
        id: gamePriceText
        anchors.bottom: parent.bottom
        anchors.left: parent.left
        anchors.leftMargin: parent.width/4
        anchors.bottomMargin: parent.height/6
        width: parent.width/2
        height: parent.height/6        
        color: "#fff"
        text: "Some text"
        font.pixelSize: 20
        font.bold: true      
    }
    

    }@

    ComboBox.qml
    @import QtQuick 1.0

    FocusScope {
    id: comboBox

    property string initialText
    property int maxHeight
    property int selectedItem: 0
    property variant listModel
    signal expanded
    signal closed
    
    ComboBoxButton {
        id: comboBoxButton
        width: parent.width
        height: parent.height
        source: "images/down.png"
        borderColor: "#fff"
        radius: 10
        margin: 5
        borderWidth: 2
        text: initialText
        textSize: parent.height-20
        
        onClicked: {
            if (listView.height == 0) {
                listView.height = Math.min(maxHeight, listModel.count*comboBoxButton.height)
                comboBox.expanded()}
            else {
                listView.height = 0
                comboBox.closed()}                
        }
    }
    
    Component {
        id: comboBoxDelegate
    
        Rectangle {
            id: delegateRectangle
            width: comboBoxButton.width
            height: comboBoxButton.height
            color: "#00000000"
            radius: comboBoxButton.radius
            border.width: comboBoxButton.borderWidth
            border.color: comboBoxButton.borderColor
    
            Item {
                anchors.left: parent.left
                width: parent.width-parent.height-2*comboBoxButton.margin
                anchors.top: parent.top
                anchors.bottom: parent.bottom
                // anchors.leftMargin: comboBoxButton.margin*2
                
                Text {
                    //color: "#fff"
                    color: index == listView.currentIndex ? "#ffff00" : "#ffffff"
                    anchors.centerIn: parent
                    font.pixelSize: comboBoxButton.height-20
                    text: value
                    font.bold: true
                }
            }
            
            MouseArea {
                anchors.fill: parent
                
                onClicked: {
                    listView.height = 0
                    listView.currentIndex = index
                    comboBox.selectedItem = index
                    comboBoxButton.text = value
                    comboBox.closed()
                }
            }
        }
    }
    
    ListView {
        // visible: false
        id: listView
        anchors.top: comboBoxButton.bottom
        anchors.left: comboBoxButton.left
        width: parent.width
        //height: Math.min(maxHeight, listModel.count*comboBoxButton.height)
        height: 0
        clip: true
        model: listModel
        delegate: comboBoxDelegate
        currentIndex: selectedItem
    
        Behavior on height {
        
            NumberAnimation {
                id: animateHeight
                property: "height"
                //from: 0.99
                //to: 1.0
                //loops: Animation.Infinite
                duration: 200
                easing {type: Easing.Linear}
            }
        }            
    }    
    

    }@



  • And the last component:

    ComboBoxButton.qml
    @import QtQuick 1.0

    FocusScope {
    id: container
    signal clicked
    property string source
    property string text
    property string color: "#ffffff"
    property int textSize: 12
    property string borderColor: "#00000000"
    property int borderWidth: 0
    property int radius: 0
    property int margin: 0

    Rectangle {
        id: buttonRectangle
        anchors.fill: parent
        color: "#00000000"
        radius: container.radius
        border.width: container.borderWidth
        border.color: container.borderColor
    
        Image {
            id: image
            smooth: true
            fillMode: Image.PreserveAspectFit
            anchors.right: parent.right
            anchors.top: parent.top
            height: parent.height-2*container.margin
            width: parent.height
            anchors.topMargin: container.margin
            anchors.bottomMargin: container.margin
            anchors.leftMargin: container.margin
            anchors.rightMargin: container.margin
            source: container.source 
        }
    
        Item {
            anchors.left: parent.left
            anchors.right: image.left
            anchors.top: parent.top
            anchors.bottom: parent.bottom
            anchors.leftMargin: container.margin*2
            
            Text {
                color: container.color
                anchors.centerIn: parent
                font.pixelSize: container.textSize
                text: container.text+" "
                font.bold: true
            }
        }
    
        MouseArea {
            id: mouseArea;
            anchors.fill: parent
            onClicked: {
                buttonRectangle.state = "pressed"
                stateTimer.start()            
                container.clicked()
            }
        }
    
        states: State {
            name: "pressed"
            PropertyChanges { target: image; scale: 0.7 }
        }
    
        Timer {
            id: stateTimer
            interval: 200;
            repeat: false
            onTriggered: buttonRectangle.state = 'State0'
        }
    
        transitions: Transition {
            NumberAnimation { properties: "scale"; duration: 200; easing.type: Easing.InOutQuad }
        }
    }
    

    }
    @

    Put an image file with arrow down to "images/down.png".





  • @Andre
    Could you elaborate more please. I do not quite understand how the "toplevel window" article will help with for example a listview expanding outside the QML area.



  • Well, basically, the dropdown of a combobox is like a menu or a list view that is layered on top of other windows. Just like menu's and other top level widgets, it may fall outside of the original area of the application. Without the ability to show top level windows, this is a problem. It would be good idea to make sure that a combo box used the top level window facilities (in the same way menus do) to show the list on.



  • Thank you all for your help :D. I now have a working combo box, but I have a follow-up question regarding the listelement values. How do I use them in an if statement?

    e.g. if (listelementvalue == "something")

    Thanks again! :)


Log in to reply
 

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