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

来源:互联网 发布:哈尔滨工业大学 知乎 编辑:程序博客网 时间:2024/05/16 01:09

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。




阅读全文
0 0
原创粉丝点击