qml自定义Combobox
2017-05-11 20:09
176 查看
qml自定义具有二级菜单的Combobox
qml自定义具有二级菜单的Combobox废话
先来看看效果
设计思路
上代码
废话
由于项目需要计划做个多级菜单,后来因为项目的特殊性放弃了这种多级菜单,但是觉得这种菜单应该挺有意思,所以在闲暇时候还是做了一个具有二级菜单的Combobox。先来看看效果
-☞表示具有有子菜单
设计思路
其实比较简单!界面效果是一个文本框和一张图片组合,加两个列表菜单组成的,具体代码中可以很清楚看到,Combobox中数据是通过ListModel填充。
上代码
控件是由纯qml完成的不涉及c++,控件部分总共用了两个qml文件(一个文件也可以,无关紧要),还有一个是main.qml是调用控件的.ComboBoxButton.qml:
import QtQuick 2.2 FocusScope { id: container signal clicked property alias source: image.source property alias text: label.text property color textColor: "white" property color borderColor: "limegreen" property color backgroundColor: "transparent" property int borderWidth: 2 property int textSize: 12 property int radius: 5 property int margin: 0 Rectangle { id: buttonRectangle anchors.fill: parent color: container.backgroundColor radius: container.radius border{width: container.borderWidth; color: container.borderColor;} Image { id: image smooth: true fillMode: Image.PreserveAspectFit anchors{top: parent.top; right: parent.right; margins: container.margin;} width: parent.height; height: parent.height-2*container.margin } Item { anchors{top: parent.top; bottom: parent.bottom; left: parent.left; right: image.left; leftMargin: container.margin * 2;} Text { id: label color: container.textColor anchors.centerIn: parent font{pixelSize: container.textSize-5; bold: true;} } } MouseArea { id: mouseArea; anchors.fill: parent onClicked: { buttonRectangle.state = "pressed" container.clicked() } } states: State { name: "pressed" PropertyChanges { target: image; scale: 0.7 } } transitions: Transition { NumberAnimation { properties: "scale"; duration: 200; easing.type: Easing.InOutQuad } } } }
Mycombobox.qml:
import QtQuick 2.2 FocusScope { id: comboBox property int maxHeight: 1000 property alias currentIndex: listView.currentIndex property alias currentIndex2: delegatelistview.currentIndex property alias buttonTextSize: comboBoxButton.textSize property alias text: comboBoxButton.text property bool readOnly: false property variant listModel property int beforeDropIndex:0 property int beforeDropIndex2: 0 property color textColor: "white" property color borderColor: "olivedrab" property color backgroundColor: "#FF00688A" property color focus_borderColor: "lightsalmon" property color focus_backgroundColor: "#FF00688A" property color focus_textColor: "darkred" signal comboBoxSelected(int idx,int index) signal comboBoxTextChanged(string comboxtext) width: 160; height: 32 z: listBackground.height===0 ? 0 : 100 ComboBoxButton { id: comboBoxButton anchors.fill: parent; source: "ico/down.png" text: typeof(listModel) == "undefined"? "":typeof( listModel.get(currentIndex).attributes)=="undefined"?listModel.get(comboBox.currentIndex).name:listModel.get(currentIndex).attributes.get(currentIndex2).description textSize: parent.height-4 textColor: comboBox.activeFocus ? comboBox.focus_textColor : comboBox.textColor borderColor: comboBox.activeFocus ? comboBox.focus_borderColor : comboBox.borderColor backgroundColor: comboBox.activeFocus ? comboBox.focus_backgroundColor : comboBox.backgroundColor onClicked: comboxClick() } Component { id: comboBoxDelegate Item { id:comitem width: parent.width; height: comboBoxButton.height; Text { id:comtext color: index == listView.currentIndex ? "#ffff00" : "white" anchors.centerIn: parent font{pixelSize: comboBoxButton.textSize-5; bold: true;} text:name } Text{ id:icotext color:"white" text:typeof(listModel.get(index).attributes) == "undefined"?"":"☞"; font{pixelSize: comboBoxButton.textSize-5; bold: true;} anchors{top:parent.top;right: parent.right} verticalAlignment: TextInput.AlignVCenter } MouseArea { anchors.fill: parent onClicked: comboBox.comboxSelect(index); } onFocusChanged: {delegatelistview.visible=true;} } } Component { id: delegate Item { width: parent.width; height: comboBoxButton.height; Text { id:comtext color:"white" anchors.centerIn: parent font{pixelSize: comboBoxButton.textSize-5; bold: true;} text:description; } MouseArea { anchors.fill: parent onClicked: comboBox.comboxSelect2(index); } onFocusChanged: {delegatelistview.visible=true;} Keys.onPressed: { if(event.key===Qt.Key_Enter||event.key===Qt.Key_Return) { comboBox.comboxClick(); } } } } Rectangle{ id:delegateback x:listView.x+listView.width y:listBackground.y+listView.currentIndex*listView.highlightItem.height color:"#FF000000" radius: comboBoxButton.radius visible: false border{width: comboBoxButton.borderWidth; color: comboBoxButton.borderColor;} ListView { id:delegatelistview anchors.fill: parent visible:false clip:true delegate: delegate keyNavigationWraps :true highlight: Rectangle{color: delegatelistview.focus?"#FF00688A":"transparent"; radius: 5;} } Behavior on height { NumberAnimation {property: "height"; duration: 200 } } state: "Hide" states: [ State { name: "Hide" PropertyChanges {target: delegateback; visible:false;height:0;width:0} StateChangeScript{ script: { delegatelistview.focus=false } } }, State { name: "Show" PropertyChanges {target: delegateback;visible:typeof(delegatelistview.model) == "undefined"?false:true; focus: false;height: Math.min(maxHeight, typeof(delegatelistview.model) == "undefined"?0:delegatelistview.model.count*comboBoxButton.height);width:comboBoxButton.width} StateChangeScript{ script: { } } } ] } ListModel{id:model} Rectangle { id: listBackground anchors{top: comboBoxButton.bottom; left: comboBoxButton.left;} width: parent.width color: "#FF000000" radius: comboBoxButton.radius border{width: comboBoxButton.borderWidth; color: comboBoxButton.borderColor;} ListView { id: listView anchors.fill: parent clip: true focus:true model:listModel delegate: comboBoxDelegate highlight: Rectangle{color:"#FF00688A"; radius: 5;} onCurrentIndexChanged: {delegatelistview.model=listModel.get(currentIndex).attributes;} } Behavior on height { NumberAnimation {property: "height"; duration: 200 } } } function comboxSelect2(index) { currentIndex2=index console.log(index) state="Close" } function comboxSelect(index){ currentIndex = index state = "Close" } function comboxClick(){ if(readOnly) return forceActiveFocus() if (state == "Close"){ state = "Drop" delegatelistview.model=listModel.get(currentIndex).attributes } else{ state = "Close" delegateback.state="Hide" } } onActiveFocusChanged: { if(!activeFocus) state = "Close" } onStateChanged: {if(state=="Close")delegateback.state="Hide"} state: "Close" states: [ State { name: "Close" PropertyChanges {target: listBackground; height: 0} StateChangeScript{ script: { if(currentIndex===beforeDropIndex&¤tIndex2===beforeDropIndex2) return comboBoxSelected(currentIndex,currentIndex2) comboBoxTextChanged(text) delegateback.state="Hide" } } }, State { name: "Drop" PropertyChanges {target: listBackground; height: Math.min(maxHeight, listModel.count*comboBoxButton.height); focus: true} StateChangeScript{ script: { beforeDropIndex = currentIndex beforeDropIndex2=currentIndex2 delegateback.state="Show" } } } ] Keys.onUpPressed: { if(state == "Drop"){ listView.decrementCurrentIndex(); return} event.accepted = false } Keys.onDownPressed: { if(state == "Drop"){ listView.incrementCurrentIndex(); return} event.accepted = false } Keys.onReturnPressed: { if(typeof(delegatelistview.model) == "undefined") { comboxClick(); return} listView.focus=false; delegatelistview.forceActiveFocus(); event.accepted = false } Keys.onEnterPressed: { if(typeof(delegatelistview.model) == "undefined") { comboxClick(); return} listView.focus=false; delegatelistview.forceActiveFocus(); event.accepted = false} Keys.onRightPressed: {if(typeof(delegatelistview.model) == "undefined")return;listView.focus=false;delegatelistview.forceActiveFocus();event.accepted = false} Keys.onLeftPressed: {if(delegatelistview.focus)listView.forceActiveFocus();event.accepted = false;} Keys.onPressed: { if(event.key === Qt.Key_Escape){ if(state !== "Close"){ state = "Close" event.accepted = true } } } }
main.qml:
import QtQuick 2.3 import QtQuick.Window 2.2 import "./" Window { visible: true MouseArea { anchors.fill: parent onClicked: { // Qt.quit(); } } Mycombobox{listModel: fruitModel;anchors.centerIn: parent} ListModel { id: fruitModel ListElement { name: "Apple" attributes: [ ListElement { description: "Core" }, ListElement { description: "Deciduous" } ] } ListElement { name: "Orange" attributes: [ ListElement { description: "Citrus" } ] } ListElement { name: "mango" } ListElement { name: "Banana" attributes: [ ListElement { description: "Tropical" }, ListElement { description: "Seedless" }, ListElement { description: "Yellow" } ] } } }
相关文章推荐
- Qt-QML-ComboBox-自定义,实现状态表示,内容可以动态正价,使用ListModel
- Qml-Dialog不能隐藏标题栏和按钮自定义
- QML之CheckBox与ComboBox
- combobox绑定自定义Item
- 看了一篇介绍如何自定义datagridview列的文章,写了一个可输入的combobox列
- QML之自定义模态可拖拽窗口
- Flex中如何利用iconFunction属性在ComboBox控件的下拉菜单中设定自定义图标的例子
- QML之自定义电池充电/电量显示效果
- QML 自定义button样式1
- QML之使用C++自定义QML类型(三)
- 为TDBLookupComboboxEh增加自定义列宽
- QML创建一个带多个下拉输入框的窗口(ComboBox)
- 自定义qml滑动条Slider
- 自定义继承的Combobox控件SelectedValue绑定无效
- Qt自定义Combobox实现列表上拉展示
- Qt-第一个QML程序-4-自定义按钮类,动画,状态
- QML中如何添加自定义的componet属性
- qml 自定义滑动条(官方example)
- QML中的Component使用--自定义一个,然后使用它
- Flex中如何通过设置fontFamily样式在ComboBox控件中使用自定义嵌入字体的例子