QML中ListView的深度订制,并利用其实现自定义ComboBox和TreeView

1、ListView的滚动条样式订制
2、基于(1、ListView的滚动条样式订制)实现一个简单的代理自定义ComboBox
3、基于(1、ListView的滚动条样式订制)实现一个复杂的代理TreeView

--------------------------------------------------------------

1、ListView的滚动条样式订制

因为 import Qt.labs.controls 1.0 的原因,会导致控件的使用和import QtQuick.Controls 1.4中的控件冲突,所以需要将订制的ListView单独封装成一个qml文件,使用的时候引入即可。
滚动条样式参考文章:http://blog.csdn.net/shado_walker/article/details/60575578
ZzListView.qml
//可以根据需求修改订制的内容  
import QtQuick 2.6  //根据QT版本变化  
import Qt.labs.controls 1.0  
ListView {  
    property alias scrollBarVisible: scrollBar.visible  //设置滚动条的可见性  
    boundsBehavior: Flickable.StopAtBounds      //设置内容不能被拖动到可滑动的边界之外。  
    ScrollBar.vertical: ScrollBar {         //订制滚动条(可以其他方式订制并绑定滑动行为)  
        id: scrollBar  
        visible: false  
        onActiveChanged: {  
            active = true;  
        }  
        Component.onCompleted: {  
            scrollBar.handle.color = "#33000000";   //滚动条颜色  
            scrollBar.active = true;  
            scrollBar.handle.width = 5;         //滚动条宽度  
        }  
    }  
}  
ListView的滚动条样式订制完成。2、中可以看到使用方法。

2、基于(1、ListView的滚动条样式订制)实现一个简单的代理

为了兼容XP(SP3以上)系统。
QtQuick.Controls 1.4中ComboBox在XP系统中显示不完整
Qt.labs.controls 1.0 中ComboBox样式太丑,且无法订制Style
所以可以根据订制好的ListView中加入一个简单的代理,即可实现订制的ComboBox。
要实现ComboBox的1个效果(点击弹出框之外的区域弹框会消失),这里选用Popup来实现。
ZzComboBox.qml
import Qt.labs.controls 1.0 as Pp //as Pp 解决Qt.labs.controls 1.0和QtQuick.Controls 1.4的冲突  
import QtQuick.Controls 1.4  
import QtQuick 2.6  
Rectangle {  
        id:year  
        anchors.centerIn: parent  
        border.width: 1  
        border.color: "lightblue"  
        width: 80  
        height: 20  
        Text {  
            anchors.verticalCenter: parent.verticalCenter  
            id: yearText  
            text: "2017"  
            anchors.left: parent.left  
            anchors.leftMargin: 5  
        }  
        MouseArea {  
            anchors.fill: parent  
            hoverEnabled: true  
            onEntered: {  
                year.border.color = "blue"  
            }  
            onExited: {  
                year.border.color = "lightblue"  
            }  
            onClicked: {  
                popup.open()  
            }  
        }  
     }  
  
Pp.Popup {  
            id: popup  
            x: year.x  
            y: 20  
            width: 80  
            height: 105  
            closePolicy: Pp.Popup.OnEscape | Pp.Popup.OnPressOutside    //单击弹窗外关闭弹窗  
            background: Rectangle {  
                color: "white"  
                border.color: "#bbbbbb"  
                border.width: 1  
                clip: true//防止滚动的时候内容超出边界  
                ZzListView {//1、中订制了滚动条的ListView  
                    id:listv  
                    anchors.fill: parent  
                    anchors.margins: 2  
                    currentIndex: 0  
                    clip: true//防止滚动的时候内容超出边界  
                    delegate: Rectangle {//基于1、中订制的ListView实现一个简单的代理  
                        id:deleg  
                        width: 253  
                        height: 20  
                        color: "white"  
                        Text {  
                            id:text  
                            anchors.verticalCenter: parent.verticalCenter  
                            anchors.left: parent.left  
                            anchors.leftMargin: 5  
                            text: name  
                        }  
                        MouseArea {  
                            anchors.fill: parent  
                            hoverEnabled: true  
                            onEntered: {  
                                listv.scrollBarVisible = true//鼠标进入代理中显示滚动条  
                                deleg.color = "lightblue"  
                            }  
                            onExited: {  
                                listv.scrollBarVisible = false//鼠标离开代理后滚动条消失  
                                deleg.color = "white"  
                            }  
                            onClicked: {  
                                yearText.text = text.text  
                                popup.close()//关闭弹窗  
                            }  
                        }  
                    }  
                    model: ListModel {  
            id: listModel  
                        //model用来加载代理中显示的内容  
            //这个ComboBox弹窗中用来显示年,具体内容可以在model的完成事件中去设置  
            //如:Compenent.OnCompeneted{listModel.append({"name":"2018"})}  
            ListElement {name: "2013"}  
                        ListElement {name: "2014"}  
                        ListElement {name: "2015"}  
                        ListElement {name: "2016"}  
                        ListElement {name: "2017"}  
                    }  
                }  
            }  
        }
这样就实现了一个订制了简单代理以及滚动条的ListView,同时也实现了一个简单ComboBox的订制。

3、基于(1、ListView的滚动条样式订制)实现一个复杂的代理

通过1、和2、可以实现ListView的样式订制和简单使用,接下来在1、的基础上实现一个复杂的代理。
自定义TreeView(QML中的TreeView中的model貌似需要在C++中实现,没花时间去研究)
这里用自定义样式的ListView去实现一个4级的树,可以根据model中的level去控制树的级数。
这里的递归组件,参考了一位大牛的文章。
地址:https://www.codeproject.com/Articles/632795/QML-TreeModel-and-TreeView
代码:
//Model  
    ListModel {  
        id: objModel  
        Component.onCompleted: {  
            objModel.append({"name":"一级节点1","level":0,"subNode":[]})  
            objModel.append({"name":"一级节点2","level":0,"subNode":[]})  
            objModel.append({"name":"一级节点3","level":0,"subNode":[]})  
            objModel.get(0).subNode.append({"name":"一级节点1子节点1","level":1,"subNode":[]})  
            objModel.get(0).subNode.append({"name":"一级节点1子节点2","level":1,"subNode":[]})  
            objModel.get(0).subNode.append({"isClicked":false,"name":"一级节点1子节点3","level":1,"subNode":[]})  
            objModel.get(0).subNode.append({"name":"一级节点1子节点4","level":1,"subNode":[]})  
            objModel.get(0).subNode.get(3).subNode.append({"isClicked":false,"name":"一级节点1子节点4中子节点1","level":2,"subNode":[]})  
            objModel.get(0).subNode.get(1).subNode.append({"isClicked":false,"name":"一级节点1子节点2中子节点1","level":2,"subNode":[]})  
            objModel.get(0).subNode.get(1).subNode.append({"name":"一级节点1子节点2中子节点2","level":2,"subNode":[]})  
            objModel.get(0).subNode.get(1).subNode.get(1).subNode.append({"isClicked":false,"name":"一级节点1子节点2中子节点2中子节点1","level":3,"subNode":[]})  
            objModel.get(0).subNode.get(1).subNode.get(1).subNode.append({"isClicked":false,"name":"一级节点1子节点2中子节点2中子节点2","level":3,"subNode":[]})  
        }  
    }  
      
    //Delegate  
    Component {  
        id: objRecursiveDelegate  
        Column {  
            id: objRecursiveColumn  
            Rectangle {  
                id:textBG  
                width: listv.width  
                height: 30  
                color: "transparent"  
                Image{  
                    id: textselectBG  
                    anchors.fill: parent  
                    source: ""  
                }  
                Image {  
                    id: image  
                    width: 12  
                    height: 12  
                    anchors.left: parent.left  
                    anchors.leftMargin: 0 == model.level ? 5 :  
                                                           1 == model.level? 20 :  
                                                                             2 == model.level? 35 : 50  
                    anchors.verticalCenter: parent.verticalCenter  
                    source: model.isClicked ? model.imgOnClicked : model.img//model中的元素被删除了。。  
                }  
                  
                Text {  
                    id:tabtext  
                    width: parent.width - 50  
                    anchors.left: image.right  
                    anchors.leftMargin: 5  
                    anchors.verticalCenter: parent.verticalCenter  
                    text: model.name  
                    elide: Text.ElideRight  
                    color: model.isClicked ? "#1b1b1b" : "#7d7d7d"  
                }  
                MouseArea {  
                    anchors.fill: parent  
                    hoverEnabled: true  
                    onEntered: {  
                        listv.scrollBarVisible = true  
                        textselectBG.source = "qrc:/img/mainView/gm_shuxingcaidan-xuanze.png"  
                    }  
                    onExited: {  
                        listv.scrollBarVisible = false  
                        textselectBG.source = ""  
                    }  
                    onClicked: {  
                        setTreeNodeColor(true, tabtext.text)  
                        for(var i = 1; i < objRecursiveColumn.children.length - 1; ++i) {  
                            objRecursiveColumn.children[i].visible = !objRecursiveColumn.children[i].visible  
                        }  
                        //setShowTab(tabtext.text)  
                    }  
                }  
            }  
              
            Repeater {  
                model: subNode  
                delegate: objRecursiveDelegate  
            }  
        }  
    }  
    //View  
    ZzListView {  
        id:listv  
        anchors.fill: parent  
        model: objModel  //关联数据模型  
        delegate: objRecursiveDelegate //关联代理  
        focus: true //可以获得焦点,这样就可以响应键盘了  
    } 
这里根据自定义的ZzListView,通过复杂的代理,实现了TreeView。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值