qml自定义Combobox

qml自定义Comboboxqml自定义具有二级菜单的Comboboxqml自定义具有二级菜单的Combobox废话先来看看效果设计思路上代码废话由于项目需要计划做个多级菜单,后来因为项目的特殊性放弃了这种多级菜单,但是觉得这种菜单应该挺有意思,所以在闲暇时候还是做了一个具有二级菜单的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&&currentIndex2===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" }
            ]
        }

    }
}


今天的文章qml自定义Combobox分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/24753.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注