[solved]How can I customize ComboBox?
-
@beidaochuan To explain here's an example:
main.qmlimport 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 useImage
element insideDropDownItem
. -
@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? -
@beidaochuan In that case use a
Loader
foritemDelegate.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? -
@beidaochuan You can put those components in respective QML files or
Component
and load it usingLoader
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 propertyCould yoy tell me the reason and how i can modified it ?
-
@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) } }
-
@beidaochuan That's good :)
If you are done, please mark the post as solved.