赞
踩
目录
本项目的交流QQ群:701889554
物联网实战--入门篇https://blog.csdn.net/ypp240124016/category_12609773.html
物联网实战--驱动篇https://blog.csdn.net/ypp240124016/category_12631333.html
本项目资源文件 https://download.csdn.net/download/ypp240124016/89317308
上图是米家APP关于分组管理的界面,主页面是选项卡+视图的模式,分组管理可以删除和排序,重命名它需要单机某个分组再进入一层界面进行操作,我们做些省略,下图是模仿的界面。
以下是针对这部分界面的项目代码结构图,主要分为两部分,一是分组切换页面——GroupTabView,二是分组管理页面——GroupEditView,其它都是对话框类型的,下面对这些内容做具体讲解。
分组就是下图红框里的内容,每个名称都是一个选项卡,下面对应的界面内容也会跟着切换,原本想着用QT自带的TabView来实现,后面发现达不到想要的效果,实际上米家APP里的选项卡和页面内容是分开的,是通过当前页面值关联起来的。所以后面就自己实现了这个过程,相对比较啰嗦点。
- import QtQuick 2.7
- import QtQuick.Controls 2.12
- import "../base"
- Rectangle
- {
- color: "transparent"
- ListView//滑动tab bar
- {
- id:id_tabBarView
- clip:true
- orientation: ListView.Horizontal
- height: 40
- anchors
- {
- left:parent.left
- right:id_listButton.left
- }
- model: ListModel{
- id:id_tabBarModel
- }
- delegate: Rectangle{
- height: 40
- width: id_titleText.contentWidth+15
- color: "transparent"
- Text{
- id:id_titleText
- height: parent.height
- width: 20
- anchors.centerIn: parent
- font.family: Qt.platform.os === "windows" ? "宋体" : "黑体"
- font.pointSize: 18
- font.bold: id_tabBarView.currentIndex===id
- text: group_name
- verticalAlignment: Text.AlignVCenter
- horizontalAlignment: Text.AlignHCenter
- }
- MouseArea
- {
- anchors.fill: parent
- onClicked:
- {
- id_tabBarView.currentIndex=id
- }
- }
- }
- onCurrentIndexChanged:
- {
- id_mainView.currentIndex=currentIndex
- }
- }
-
- GroupNewDialog
- {
- id:id_groupNewDialog
- }
-
- GroupManDialog
- {
- id:id_groupManDialog
- onSiqNewGroup: //新建分组
- {
- id_groupNewDialog.funOpen("新分组")
- }
- onSiqManGroup: //分组管理
- {
- theAccountMan.setHomeCurrView("home-group")
- }
- onSiqOpenGroup:
- {
- id_tabBarView.currentIndex=id
- id_mainView.currentIndex=id
- }
- }
-
- Rectangle{ //列表按钮
- id:id_listButton
- height: id_tabBarView.height*0.8
- width: height*1.5
- anchors
- {
- right:parent.right
- rightMargin:15
- verticalCenter:id_tabBarView.verticalCenter
- }
-
- radius: height/2
- color: "#BFC5D6"
- ImageButton01{
- anchors.centerIn: parent
- height: parent.height*0.85
- width: height
- source: "qrc:/mainImgRC/images/home/list.png"
- onSiqClickedLeft:
- {
- id_groupManDialog.open()
- }
- }
- }
-
- SwipeView { //主页面切换
- id: id_mainView
- width: parent.width
- anchors
- {
- top:id_tabBarView.bottom
- bottom:parent.bottom
- }
- Repeater {
- model: ListModel{
- id:id_mainModel
- }
-
- Rectangle {
- color: "transparent"
- Text{
- anchors.centerIn: parent
- font.pointSize: 18
- text: id
- }
- }
- }
- onCurrentIndexChanged: {
- id_tabBarView.currentIndex=currentIndex
- }
- }
- Component.onCompleted:
- {
- for(var i=0; i<1; i++)
- {
- id_tabBarModel.append({"id":i, "group_name":"全部"})
- id_mainModel.append({"id":i, "group_name":"全部"})
- }
- }
-
- Connections
- {
- target: theCenterMan
- onSiqAddGroup:
- {
- if(index===0)
- {
- id_tabBarModel.clear()
- id_mainModel.clear()
- id_tabBarModel.append({"id":0, "group_name":"全部"})
- id_mainModel.append({"id":0, "group_name":"全部"})
- }
- index=id_tabBarModel.count
- id_tabBarModel.append({"id":index, "group_name":group_name})
- id_mainModel.append({"id":index, "group_name":group_name})
- }
- onSiqRenameGroup:
- {
- for(var i=1; i<id_tabBarModel.count; i++)
- {
- var group_name=id_tabBarModel.get(i).group_name
- if(group_name===old_name)
- {
- id_tabBarModel.setProperty(i, "group_name", new_name)
- id_mainModel.setProperty(i, "group_name", new_name)
- break
- }
- }
- }
- onSiqDelGroup:
- {
- for(var i=1; i<id_tabBarModel.count; i++)
- {
- if(group_name===id_tabBarModel.get(i).group_name)
- {
- id_tabBarModel.remove(i)
- id_mainModel.remove(i)
- break
- }
- }
- }
- }
- }
-
-
-
-
-
分组切换具体代码如上所示,主要分为Tab和View两部分,Tab用一个ListView,这样就可以实现滑动而不切换的效果了,如果是QT的TabView,点一下就会切换过去,没法用。
ListView核心就两个内容,模型和单元格,即model和delegate两个属性,模型一般采用ListModel,通过操作ListModel实例就可以改变单元格的内容以及增减单元格等操作了。delegate就是单元格具体内容了,在这里主要就是文本,另外背景的矩形要改成透明的,这样APP的背景色才能透出来,还有一个是鼠标,点击后会触发切换,tab切换后又会联动下方的主视图切换,这样两者就关联起来了。
主页面是一个SwipeView ,这个是之前常用的模块了,后面这个页面是要承载设备显示用的,暂时没什么用处,就显示个页码。
在tab的右边有一个按钮,是触发分组管理用的,下面是分组管理的具体代码,是一个对话框,显示内容有三个——新建分组、编辑分组和各分组的显示。其中分组显示采用一个ListView列表视图,显示组名和组内设备数量。
- import QtQuick 2.7
- import QtQuick.Controls 2.14
- import "../base"
- //分组管理弹框
-
- Popup {
- signal siqNewGroup()
- signal siqManGroup()
- signal siqOpenGroup(var id, var group_name)
- property var rowHeight: 40
- id:id_popup
- visible: false
- implicitWidth: parent.width*0.6
- implicitHeight: rowHeight*(id_listModel.count+2)+id_popup.topPadding+id_popup.bottomPadding
- modal: true
- focus: true
- closePolicy: Popup.CloseOnEscape | Popup.CloseOnReleaseOutside
-
- x:parent.width*0.3
- y:10
-
-
- background: Rectangle
- {
-
- radius:15
- }
- Rectangle//分割横线
- {
- id:id_lineRect
- width: parent.width*0.8
- height: 1
- color:"#F0F0F0"
- anchors
- {
- horizontalCenter:parent.horizontalCenter
- bottom:parent.bottom
- bottomMargin:rowHeight*2
- }
- }
- TextButton01//新建按钮
- {
- id:id_newButton
- height: rowHeight
- width: parent.width
- anchors
- {
- left:parent.left
- leftMargin:10
- top:id_lineRect.bottom
- }
- textValue: "新建"
- onSiqClickedLeft:
- {
- id_popup.close()
- siqNewGroup()
- }
- Image//新建图标
- {
- width: height
- height: parent.height*0.6
- mipmap: true
- anchors
- {
- verticalCenter:parent.verticalCenter
- right:parent.right
- rightMargin:15
- }
- source: "qrc:/mainImgRC/images/home/new.png"
- }
- }
-
- TextButton01//分组管理
- {
- id:id_manButton
- height: id_newButton.height
- width: parent.width
- anchors
- {
- left:parent.left
- leftMargin:10
- top:id_newButton.bottom
- }
- textValue: "管理"
- onSiqClickedLeft:
- {
- id_popup.close()
- siqManGroup()
- }
- Image//管理图标
- {
- width: height
- height: parent.height*0.5
- mipmap: true
- anchors
- {
- verticalCenter:parent.verticalCenter
- right:parent.right
- rightMargin:17
- }
- source: "qrc:/mainImgRC/images/home/man.png"
- }
- }
-
- ListView
- {
- clip: true
- width: parent.width
- anchors
- {
- top:parent.top
- bottom:id_lineRect.top
- }
- model: ListModel{
- id:id_listModel
- }
-
- delegate: Rectangle{
- height: rowHeight
- width: parent.width
- TextButton01//分组按钮
- {
- id:id_groupButton
- height: rowHeight
- width: parent.width-20
- anchors
- {
- left:parent.left
- leftMargin:10
- verticalCenter:parent.verticalCenter
- }
- textValue: group_name
- onSiqClickedLeft: //打开某个分组
- {
- id_popup.close()
- siqOpenGroup(id, group_name)
- }
- Text{
- id:id_totalNumText
- height: parent.height
- width: 30
- anchors{
- right: parent.right
- verticalCenter: parent.verticalCenter
- }
- color: "#808080"
- font.family: "宋体"
- font.pointSize: 18
- text: total_num
- verticalAlignment: Text.AlignVCenter
- horizontalAlignment: Text.AlignHCenter
- }
- }
- }
- }
-
- Component.onCompleted:
- {
- for(var i=0; i<1; i++)
- {
- id_listModel.append({"id":i, "group_name":"全部", "total_num":0})
- }
- }
-
- Connections
- {
- target: theCenterMan
- onSiqAddGroup:
- {
- if(index===0)
- {
- id_listModel.clear()
- id_listModel.append({"id":0, "group_name":"全部", "total_num":total_num})
- }
- index=id_listModel.count
- id_listModel.append({"id":index, "group_name":group_name, "total_num":total_num})
- }
- onSiqRenameGroup:
- {
- for(var i=1; i<id_listModel.count; i++)
- {
- var group_name=id_listModel.get(i).group_name
- if(group_name===old_name)
- {
- id_listModel.setProperty(i, "group_name", new_name)
- break
- }
- }
- }
- onSiqDelGroup:
- {
- for(var i=1; i<id_listModel.count; i++)
- {
- if(group_name===id_listModel.get(i).group_name)
- {
- id_listModel.remove(i)
- break
- }
- }
- }
- }
-
- }
点击 新建按钮后,会弹出新建对话框,可以输入组名进行新建操作。
编辑分组比较复杂,包含了删除、重命名和排序,其中重点是排序功能,具体代码如下。这里面主要难点是一个分组排序的拖拽功能,核心思想是—— 单元格内分为两部分,一个是拖拽有效区id_dragRect,一个是拖拽显示区dropRectangle,当鼠标捕捉到拖拽信号后,就把拖拽区的父组件从单元格修改为根矩形组件,然后取消布局,这样拖拽区就可以被拉动了;接着是放掉后检测当前坐标,看下在哪个单元格上就跟其做交换即可,最后配合ListView的move和moveDisplaced动画,产生交换效果就完成了,具体实现看代码。
- import QtQuick 2.7
- import QtQuick.Controls 2.0
- import "../base"
-
- //分组编辑界面
-
- Rectangle {
- id:id_rootRect
-
- focus: true
- MsgDialog01
- {
- id:id_msgDialog
- }
-
- Keys.onPressed:
- {
- if(event.key === Qt.Key_Back)
- {
- console.log("phone Key_Back!")
- event.accepted = true;
- theAccountMan.setHomeCurrView("home-logined")
- }
- }
-
- ImageButton01//返回按钮
- {
- id:id_backButton
- source: "qrc:/mainImgRC/images/login/back.png"
-
- anchors
- {
- left:parent.left
- leftMargin:20
- top:parent.top
- topMargin:20
- }
- onSiqClickedLeft:
- {
- theAccountMan.setHomeCurrView("home-logined")
- }
- }
- ImageButton01{
- id:id_okButton
- source: "qrc:/mainImgRC/images/home/ok.png"
- height: 35
- anchors
- {
- right:parent.right
- rightMargin:20
- verticalCenter:id_backButton.verticalCenter
- }
- onSiqClickedLeft: //完成
- {
- var str_list=[]
- for(var i=1; i<id_listModel.count; i++)
- {
- str_list[i]=id_listModel.get(i).group_name
- }
- theCenterMan.requestOrderGroup(str_list)
- }
- }
-
- GroupRenameDialog//重命名
- {
- id:id_renameDialog
- onSiqOkClicked:
- {
- if(text)
- {
- if(text==="全部")
- {
- id_msgDialog.funOpen("不能使用\"全部\"作为组名!")
- return
- }
- theCenterMan.requestRenameGroup(oldName, text)
- }
- funClose()
- }
- }
- GroupDelDialog //删除分组对话框
- {
- id:id_delGroupDialog
- onSiqOkClicked:
- {
- theCenterMan.requestDelGroup(groupName)
- funClose()
- }
- }
-
- ListView{
- property int dragItemIndex: -1
- id:id_editListView
- clip: true
- width: parent.width
- anchors
- {
- top:id_backButton.bottom
- bottom:parent.bottom
- }
- model: ListModel{
- id:id_listModel
- }
- move:Transition {
- NumberAnimation { properties: "x,y"; duration: 200 }
- }
- moveDisplaced:Transition {
- NumberAnimation { properties: "x,y"; duration: 200 }
- }
- delegate: Rectangle{
- id:id_unionRect
- height: 60
- width: parent.width
- Rectangle
- {
- id:id_dragRect
- height: id_unionRect.height
- width: id_unionRect.width
- color: id_moveMouseArea.drag.active ? "transparent" : "white"
- MouseArea
- {
- id:id_moveMouseArea
- enabled: id>0
- anchors.fill: parent
- drag.target: id_dragRect
- drag.axis: Drag.YAxis
- drag.onActiveChanged: {
- if (id_moveMouseArea.drag.active) {
- id_editListView.dragItemIndex = index;
- // console.log("index=", index)
- }
- id_dragRect.Drag.drop();
- }
- }
- states: [
- State {
- when: id_dragRect.Drag.active
- ParentChange {
- target: id_dragRect
- parent: id_rootRect
- }
-
- AnchorChanges {
- target: id_dragRect
- anchors.horizontalCenter: undefined
- anchors.verticalCenter: undefined
- }
- }
- ]
- Drag.active: id_moveMouseArea.drag.active
- Drag.hotSpot.x: id_dragRect.width / 2
- Drag.hotSpot.y: id_dragRect.height / 2
-
- ImageButton01{
- id:id_delButton
- source: "qrc:/mainImgRC/images/home/del.png"
- height: 25
- width: height
- visible: id>0
- anchors
- {
- verticalCenter:parent.verticalCenter
- left:parent.left
- leftMargin:20
- }
- onSiqClickedLeft: //删除
- {
- id_delGroupDialog.groupName=group_name
- id_delGroupDialog.funOpen()
- }
- }
-
- Text{ //组名文本
- id:id_groupText
- height: 40
- anchors{
- left: id_delButton.right
- leftMargin: 10
- right: id_totalNumText.left
- verticalCenter: parent.verticalCenter
- }
- color: "black"
- font.family: Qt.platform.os === "windows" ? "宋体" : "黑体"
- font.pointSize: 18
- font.bold: id_moveMouseArea.pressed
- text: group_name
- verticalAlignment: Text.AlignVCenter
- horizontalAlignment: Text.AlignLeft
- elide: Text.ElideRight
- }
-
- Text{ //数量文本
- id:id_totalNumText
- height: 30
- width: 30
- anchors{
- right: id_renameButton.left
- rightMargin: 5
- verticalCenter: parent.verticalCenter
- }
- color: "#808080"
- font.family: "宋体"
- font.pointSize: 18
- text: total_num
- verticalAlignment: Text.AlignVCenter
- horizontalAlignment: Text.AlignLeft
- elide: Text.ElideRight
- }
- ImageButton01{
- id:id_renameButton
- source: "qrc:/mainImgRC/images/home/rename.png"
- height: 25
- width: height
- visible: id>0
- anchors
- {
- verticalCenter:parent.verticalCenter
- right:parent.right
- rightMargin:20
- }
- onSiqClickedLeft: //重命名
- {
- id_renameDialog.oldName=group_name
- id_renameDialog.funOpen(group_name)
- }
- }
-
-
- }
- DropArea {
- id: dropArea
- anchors.fill: parent
- onDropped:{
- // console.log("onDropped")
- var other_index = id_editListView.indexAt(id_moveMouseArea.mouseX + id_unionRect.x, id_moveMouseArea.mouseY + id_unionRect.y);
- // console.log("index:",index,"other_index:",other_index,"listView.dragItemIndex:",id_editListView.dragItemIndex);
- if(other_index>0)
- {
- id_listModel.move(id_editListView.dragItemIndex,other_index, 1);
- }
- }
-
- Rectangle {
- id: dropRectangle
-
- anchors.fill: parent
- color: "transparent"
-
- states: [
- State {
- when: dropArea.containsDrag
- PropertyChanges {
- target: dropRectangle
- color: "lightsteelblue"
- opacity:0.3
- }
- }
- ]
- }//end Rectangle
-
- }//end drop
-
- }
- }
- Component.onCompleted:
- {
- for(var i=0; i<1; i++)
- {
- id_listModel.append({"id":i, "group_name":"全部", "total_num":0})
- }
- }
- Connections
- {
- target: theCenterMan
- onSiqAddGroup:
- {
- if(index===0)
- {
- id_listModel.clear()
- id_listModel.append({"id":0, "group_name":"全部", "total_num":total_num})
- }
- index=id_listModel.count
- id_listModel.append({"id":index, "group_name":group_name, "total_num":total_num})
- }
- onSiqRenameGroup:
- {
- for(var i=1; i<id_listModel.count; i++)
- {
- var group_name=id_listModel.get(i).group_name
- if(group_name===old_name)
- {
- id_listModel.setProperty(i, "group_name", new_name)
- break
- }
- }
- }
- onSiqDelGroup:
- {
- for(var i=1; i<id_listModel.count; i++)
- {
- if(group_name===id_listModel.get(i).group_name)
- {
- id_listModel.remove(i)
- break
- }
- }
- }
- }
-
- }
删除和重命名就是相关对话框内容了,没有很复杂的内容,具体看代码。
- import QtQuick 2.7
- import QtQuick.Controls 2.14
-
- Popup {
-
- property var titleText: "标题"
- property var cancelText: "取消"
- property var okText: "确定"
- property var cancelColor: "#303030"
- property var okColor: "#303030"
-
- signal siqCancelClicked()
- signal siqOkClicked()
- id:id_popup
- visible: false
- implicitWidth: parent.width
- implicitHeight: 200
- modal: true
- focus: true
- closePolicy: Popup.CloseOnEscape | Popup.CloseOnReleaseOutside
- anchors.centerIn: Overlay.overlay
-
- background: Rectangle
- {
- radius:10
- }
-
- Text {//标题文字
- id:id_titleText
- height: 40
- width: parent.width*0.8
- anchors
- {
- top:parent.top
- topMargin:10
- horizontalCenter:parent.horizontalCenter
- }
- verticalAlignment: Text.AlignVCenter
- horizontalAlignment: Text.AlignHCenter
- font.pointSize: height*0.4
- font.family: "宋体"
- text: titleText
- color: "black"
- }
-
-
- BaseButton02//取消按钮
- {
- id:id_cancelButton
- height: 50
- width: parent.width*0.4
- releaseColor: "#F0F0F0"
- pressedColor: "#F0F0F0"
- anchors
- {
- left:parent.left
- leftMargin:20
- bottom:parent.bottom
- bottomMargin:20
- }
- buttonText: cancelText
- buttonColor:cancelColor
- onSiqClickedLeft:
- {
- siqCancelClicked()
- }
- }
- BaseButton02//确定按钮
- {
- id:id_okButton
- height: id_cancelButton.height
- width: id_cancelButton.width
- releaseColor: "#F0F0F0"
- pressedColor: "#F0F0F0"
- anchors
- {
- verticalCenter:id_cancelButton.verticalCenter
- right:parent.right
- rightMargin:20
- }
- buttonText: okText
- buttonColor:okColor
- onSiqClickedLeft:
- {
- siqOkClicked()
- }
- }
-
- function funOpen()
- {
- id_popup.open()
- }
-
- function funClose()
- {
- id_popup.close()
- }
- }
-
- import QtQuick 2.0
- import "../base"
-
- //删除警示对话框
-
-
- BaseWarnDialog {
-
- titleText: "确认删除分组吗?"
- property var groupName: ""
-
- okText: "删除"
- okColor: "#F00000"
- onSiqCancelClicked:
- {
- funClose()
- }
-
-
- }
- import QtQuick 2.0
- import "../base"
-
- //重命名分组对话框
-
-
- BaseEditDialog {
-
- titleText: "重命名分组"
- property var oldName: ""
- onSiqCancelClicked:
- {
- funClose()
- }
-
-
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。