[solved]How can I customize ComboBox?



  • I made a qml element "ImageUser" and I want to make a ImageComboBox that its drop down items are ImageUser. how can i implement it?? (combobox has no delegate (cry))


  • Moderators



  • @p3c0
    can the style do what I want ?


  • Moderators

    @beidaochuan What do you want to do ? Can you provide a screenshot or some code sample ?



  • @p3c0
    i am sorry. could you tell me how i can upload a image.


  • Moderators

    @beidaochuan Upload it to one of the image hosting sites like postimage.org or imgur.com or tinypic.com. Then after uploading there it will return a url. Post that url here directly or to embed it here use syntax ![Alt text](/path/to/img.jpg)



  • @p3c0
    Thank you.
    usual combobox Alt text
    so i want to replace "banana/apple/coconut" with the qml element img


  • Moderators

    @beidaochuan Still trying to understand. The image in the second link will be one of the item of ComboBox ?



  • @p3c0
    yes. the second image is one of the items of combobox. In fact the second image is a qml element.


  • Moderators

    @beidaochuan Ok then to make your own custom dropdown. For now, you will need to implement your own dropdown style using __dropDownStyle private property inside ComboBoxStyle.


  • Moderators

    @beidaochuan To explain here's an example:
    main.qml

    import QtQuick 2.4
    import QtQuick.Controls 1.3
    import QtQuick.Controls.Styles 1.3
    
    Item {
        width: 250
        height: 120
    
        ComboBox {
            model: ListModel {
                id: cbItems
                ListElement { text: "Banana"; color: "Yellow" }
                ListElement { text: "Apple"; color: "Green" }
                ListElement { text: "Coconut"; color: "Brown" }
            }
            width: 200
    
            style: ComboBoxStyle {
                id: comboBoxStyle
                background: Rectangle {
                    id: rect
                    border.color: "red"
                    color: "white"
                }
    
                label: Text {
                    color: "black"
                    text: control.currentText
                }
    
                __dropDownStyle: MenuStyle {
                    frame: DropDownItem { }
    
                    itemDelegate.label: Text {
                        color: styleData.selected ? "red" : "black"
                        text: styleData.text
                    }
                }
            }
        }
    }
    

    DropDownItem.qml

    import QtQuick 2.4
    
    Rectangle {
        color: "white"
        border.width: 1
        radius: 5
        border.color: "gray"
    }
    

    Now you can change DropDownItem as per your needs. I see you have some images in it. So you can use Image element inside DropDownItem.



  • @p3c0
    thank you for your apply.
    I will try to do as you said.
    have a nice day.



  • @p3c0
    i did as you said, and modified the source as follows.

    itemDelegate.background: IUserLevelImage{ userLevel: combx.currentIndex + 1}
    frame: DropDownItem { }

    And get the result like http://imgur.com/m4QW7c6
    But I want to get the different background for banana , apple and coconut
    what should i do?


  • Moderators

    @beidaochuan In that case use a Loader for itemDelegate.background and load the Components (in your case QML files) as per conditions. Each Component will contain individual styles.

    itemDelegate.background: Loader {
        source: if(styleData.text==="Coconut") {
                    return "CoconutStyle.qml"
                } else if(styleData.text==="Banana") {
                    return "BananaStyle.qml"
                } else if(styleData.text==="Apple") {
                    return "AppleStyle.qml"
                }
    }
    


  • This post is deleted!


  • @p3c0
    Thanks at first.
    I am sorry that maybe I did not make the problem clear.
    I want to implement a custom ComboBox whose items can be text , image, or object (***.qml).
    So I think it would be common for all case.
    Could you give me some advice?


  • Moderators

    @beidaochuan You can put those components in respective QML files or Component and load it using Loader as shown in previous post.



  • @p3c0
    I modified the code like:

    //IComboBox
    
    import QtQuick 2.3
    import QtQuick.Controls 1.3
    import QtQuick.Controls.Styles 1.3
    
    Item {
        id: root
        width: 200
        height: 50
    
        property alias comboBoxModel: combx.model
        property alias comboBoxStyleBackground: m_comboBoxStyle
        property alias dropDownMenuStyleframe: m_dropDownMenuStyleFrame
        signal indexChanged()
        property alias currentIndex: combx.currentIndex
        property alias currentText: combx.currentText
    
        Rectangle {
            id: m_dropDownMenuStyleFrame
        }
    
        Rectangle {
            id: m_comboBoxStyle
        }
    
        ComboBox {
            id: combx
            model: ListModel {
                id: cbItems
            }
            width: 200
            height: 50
            style: ComboBoxStyle {
                id: comboBoxStyle
                background: m_comboBoxStyle
                label: Text {
                    color: "black"
                    width: 200
                    height: 50
                    text: control.currentText
                }
    
                __dropDownStyle: MenuStyle {
                    id: dropDownMenuStyle
                    frame: dropDownMenuStyleFrame
                    itemDelegate.label: Text {
                        width:200
                        height: 50
                        color: styleData.selected ? "blue" : "black"
                        text: styleData.text
                    }
    
                    itemDelegate.background: Rectangle {
                        z: 1
                        opacity: 0.5
                        color: styleData.selected ? "darkGray" : "transparent"
                    }
                }
            }
            onCurrentIndexChanged: {
                root.indexChanged()
            }
        }
    }
    

    I use it in another my.qml,

    // my.qml
    import QtQuick 2.3
    import QtQuick.Controls 1.3
    import QtQuick.Controls.Styles 1.3
    
    IComboBox {
        id: root
        width: 200
        height: 50
    
        property int m_userLevel: 1
        comboBoxModel: ListModel {
            id: cbItems
            ListElement { }
            ListElement { }
            ListElement { }
            ListElement { }
        }
        comboBoxStyleBackground: IUserLevelImage {
            userLevel: m_userLevel
        }
        dropDownMenuStyleframe: IUserLevelImage1 {
            id: items
        }
        onIndexChanged: {
            m_userLevel = currentIndex + 1
        }
    }
    

    So an error happened.
    Invalid property assignment: "dropDownMenuStyleframe" is a read-only property

    Could yoy tell me the reason and how i can modified it ?



  • @p3c0
    By the way, how should i post the code using format?


  • Moderators

    @beidaochuan That is because alias'es work with Component's properties and not with Components. More info here. The example should explain.
    Put your code after ``` (3 backticks) and end with the same. I have done it for you now.



  • @p3c0
    I modified the source as follows and I think it works well.

    //IComboBox
    import QtQuick 2.3
    import QtQuick.Controls 1.3
    import QtQuick.Controls.Styles 1.3
    
    ComboBox {
        id: root
        width: 200
        height: 50
    
        property alias comboBoxModel: root.model
        signal indexChanged()
        property alias currentIndex: root.currentIndex
        property alias currentText: root.currentText
    
        property Component comboBoxStyleBackground: Component { Rectangle{} }
        property Component dropDownMenuStyleFrame: Component { Rectangle{} }
    
        function setComboBoxStyleBackground(background) {
            comboBoxStyleBackground = background
        }
    
        function setDropDownMenuStyleFrame(frame) {
            dropDownMenuStyleFrame = frame
        }
    
        model: ListModel {
            id: cbItems
            ListElement { text: "" }
        }
    
        style: ComboBoxStyle {
            id: comboBoxStyle
            background: comboBoxStyleBackground
            label: Text {
                color: "black"
                width: root.width
                height: root.height
                text: control.currentText
            }
    
            __dropDownStyle: MenuStyle {
                id: dropDownMenuStyle
                frame: dropDownMenuStyleFrame
                itemDelegate.label: Text {
                    width:root.width - 50
                    height: root.height
                    color: styleData.selected ? "blue" : "black"
                    text: styleData.text
                }
    
                itemDelegate.background: Rectangle {
                    z: 1
                    opacity: 0.5
                    color: styleData.selected ? "darkGray" : "transparent"
                }
            }
        }
    
        onCurrentIndexChanged: {
            root.indexChanged()
        }
    }
    
    //MyComboBox
    import QtQuick 2.3
    import QtQuick.Controls 1.3
    import QtQuick.Controls.Styles 1.3
    
    IComboBox {
        id: root
        width: 200
        height: 50
    
        property int m_userLevel: 1
        comboBoxModel: ListModel {
            id: cbItems
            ListElement { text: "" }
            ListElement { text: "" }
            ListElement { text: "" }
            ListElement { text: "" }
        }
    
    
        Component {
            id: comboBoxStyleBackground
            IUserLevelImage {
                anchors.fill: parent
                userLevel: m_userLevel
            }
        }
    
    
        Component {
            id: dropDownMenuStyleFrame
            IUserLevelImage1 {
            }
        }
        onIndexChanged: {
            m_userLevel = currentIndex + 1
        }
        Component.onCompleted: {
            setComboBoxStyleBackground(comboBoxStyleBackground)
            setDropDownMenuStyleFrame(dropDownMenuStyleFrame)
        }
    }
    

  • Moderators

    @beidaochuan That's good :)
    If you are done, please mark the post as solved.


Log in to reply
 

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