Qml Gridview移动显示标记
需求
在原有的gridview的已经显示了model中的图片数据,现在需要在到不同的item上根据不同的标签状态和收藏状态显示现在的结果示例图:
- 鼠标移动到gridview上,当便签为空的时候,左边的图就是正常状态,并且移开的时候消失,如果标签不为空的时候,左边的图片高亮,并且移开鼠标不消失。
- 鼠标移动到gridview上,当图片没有被收藏的时候,右边的桃心是空心的,鼠标移开的时候消失,当图片被收藏的时候,图片如上显示红心,并且鼠标移开不消失。
- 其中有个需求在截图中看不出来,这是一个左下角的背景矩形是要单独圆角处理的。
实现
首先我们要处理这个圆角(参考的是github的源码,并做了修改)参考地址
import QtQuick 2.12
import QtQuick.Controls 2.5
import QtQuick.Shapes 1.12
Shape {
id: root
property bool leftTopRound: false
property bool leftBottomRound: false
property bool rightTopRound: false
property bool rightBottomRound: false
property real radius: 5
property color color: "red"
antialiasing: true
ShapePath {
fillColor: color
strokeColor: "transparent" //这里需要处理边线为透明的
startX: leftTopRound ? radius : 0
startY: 0
PathLine {
x: rightTopRound ? root.width - radius : root.width
y: 0
}
PathArc {
x: root.width
y: rightTopRound ? radius : 0
radiusX: rightTopRound ? radius : 0
radiusY: rightTopRound ? radius : 0
}
PathLine {
x: root.width
y: rightBottomRound ? root.height - radius : root.height
}
PathArc {
x: rightBottomRound ? root.width - radius : root.width
y: root.height
radiusX: rightBottomRound ? radius : 0
radiusY: rightBottomRound ? radius : 0
}
PathLine {
x: leftBottomRound ? radius : 0
y: root.height
}
PathArc {
x: 0
y: leftBottomRound ? root.height - radius : root.height
radiusX: leftBottomRound ? radius : 0
radiusY: leftBottomRound ? radius : 0
}
PathLine {
x: 0
y: leftTopRound ? radius : 0
}
PathArc {
x: leftTopRound ? radius : 0
y: 0
radiusX: leftTopRound ? radius : 0
radiusY: leftTopRound ? radius : 0
}
}
}
在使用的时候,有一个地方值得注意,因为我们的项目已经有运行目录了,所以在使用shapes的时候需要将编译环境下面的 qt安装路径\编译版本\qml\QtQuick\Shapes拷贝到运行目录下面,如果你是在dome中是没有问题的。
然后定义这个区域的控件显示
/**
*author : Teacher zeng
*Create data : 2020.06
*functional description: 移动鼠标显示当前图片的标签和收藏信息
*难点1:透明显示的时候,显示一个圆角
*难点2:不同状态下的靠左显示
*难点3:动态获取Tag的状态
*难点4:需要将鼠标点击事件传递到这一层 传递还好,问题在于可能会影响其他的事件的作用
*/
import QtQuick 2.12
import QtQuick.Controls 2.12
import "../../basiccontrol"
CRoundRect{ //继承我们开发的支持圆角的控件
//Rectangle{
//外观设置
id:root
property bool tagflag : false //
property bool favflag : false //
property bool mouseEnter: false
signal sigfavorite
signal sigshowtag
visible: mouseEnter || tagflag || favflag
color: "#991B1F24" //为了让背景透明,但是我们的png不被透明,这个时候qml支持的颜色alpha通道就是一个十分好用的地方
// opacity: 0.6 使用透明,图片也会被透明,效果就不是很好
leftBottomRound: true
height: 16
width: 0 + (btn_tag.visible ? 20 :0) + (btn_fav.visible ? 20 :0)
CImageStatusButton{ //自定义一个四种状态的button
id:btn_tag
img_normal: "qrc:/res/view/tag.png"
img_hover: "qrc:/res/view/tag_hover.png"
img_select_normal: "qrc:/res/view/tag_press.png"
img_select_hover: "qrc:/res/view/tag_press_hover.png"
anchors.verticalCenter: parent.verticalCenter
select: tagflag //显示的状态
visible: mouseEnter || tagflag //通过状态值来判断是否显示,当鼠标进入或者标记值为ture的时候显示
onClicked:sigshowtag()
anchors.left: parent.left
anchors.leftMargin: 7
}
CImageStatusButton{
id:btn_fav
img_normal: "qrc:/res/view/favorite.png"
img_hover: "qrc:/res/view/favorite_hover.png"
img_select_normal: "qrc:/res/view/favorite_press.png"
img_select_hover: "qrc:/res/view/favorite_press_hover.png"
anchors.verticalCenter: parent.verticalCenter
select: favflag
visible: mouseEnter || favflag
onClicked:sigfavorite()
anchors.right: parent.right
anchors.rightMargin: 6
}
}
然后就是处理移动显示的问题,这个时候我们需要利用mousearea的 onPositionChanged() 槽函数处理移动选中的问题
property int mouseoverIndex : -1
hoverEnabled: true
onPositionChanged: {
var index = id_icon_view.indexAt(mouse.x, id_icon_view.contentY + mouse.y)
if (index === -1)
return
mouseoverIndex = index
}
最后处理一个小的问题,就是之前的在gridview最外层,由于之前人写的代码需要做拖动选取等效果,蒙了一层mousearea。现在需要利用鼠标的穿透事件来做这个事情,来实现状态图还要处理的点击事件。
//
propagateComposedEvents: true
onClicked: {
//这个地方我需要传很多层
mouse.accepted = false
}
//将鼠标的点击事件从底层覆盖的mouseArea -> listview.mousearea->item.mouseArea->当前区域的mouseArea()