Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. [solved]How can I customize ComboBox?

[solved]How can I customize ComboBox?

Scheduled Pinned Locked Moved QML and Qt Quick
comboboxcustomizeqmlqtquick
22 Posts 2 Posters 14.1k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B beidaochuan

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

    p3c0P Offline
    p3c0P Offline
    p3c0
    Moderators
    wrote on last edited by p3c0
    #11

    @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.

    157

    B 2 Replies Last reply
    0
    • p3c0P p3c0

      @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.

      B Offline
      B Offline
      beidaochuan
      wrote on last edited by
      #12

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

      1 Reply Last reply
      0
      • p3c0P p3c0

        @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.

        B Offline
        B Offline
        beidaochuan
        wrote on last edited by
        #13

        @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?

        p3c0P B 2 Replies Last reply
        0
        • B beidaochuan

          @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?

          p3c0P Offline
          p3c0P Offline
          p3c0
          Moderators
          wrote on last edited by p3c0
          #14

          @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"
                      }
          }
          

          157

          B 1 Reply Last reply
          0
          • B beidaochuan

            @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?

            B Offline
            B Offline
            beidaochuan
            wrote on last edited by
            #15
            This post is deleted!
            1 Reply Last reply
            0
            • p3c0P p3c0

              @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"
                          }
              }
              
              B Offline
              B Offline
              beidaochuan
              wrote on last edited by
              #16

              @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?

              p3c0P 1 Reply Last reply
              0
              • B beidaochuan

                @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?

                p3c0P Offline
                p3c0P Offline
                p3c0
                Moderators
                wrote on last edited by
                #17

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

                157

                B 2 Replies Last reply
                0
                • p3c0P p3c0

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

                  B Offline
                  B Offline
                  beidaochuan
                  wrote on last edited by p3c0
                  #18

                  @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 ?

                  1 Reply Last reply
                  0
                  • p3c0P p3c0

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

                    B Offline
                    B Offline
                    beidaochuan
                    wrote on last edited by
                    #19

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

                    p3c0P 1 Reply Last reply
                    0
                    • B beidaochuan

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

                      p3c0P Offline
                      p3c0P Offline
                      p3c0
                      Moderators
                      wrote on last edited by
                      #20

                      @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.

                      157

                      B 1 Reply Last reply
                      0
                      • p3c0P p3c0

                        @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.

                        B Offline
                        B Offline
                        beidaochuan
                        wrote on last edited by beidaochuan
                        #21

                        @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)
                            }
                        }
                        
                        p3c0P 1 Reply Last reply
                        0
                        • B beidaochuan

                          @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)
                              }
                          }
                          
                          p3c0P Offline
                          p3c0P Offline
                          p3c0
                          Moderators
                          wrote on last edited by
                          #22

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

                          157

                          1 Reply Last reply
                          0

                          • Login

                          • Login or register to search.
                          • First post
                            Last post
                          0
                          • Categories
                          • Recent
                          • Tags
                          • Popular
                          • Users
                          • Groups
                          • Search
                          • Get Qt Extensions
                          • Unsolved