qml----Model/View入门(八)PathView
pathview由model 、delegate、path三部分组成。Path的startX、startY用于描述路径的起点,而pathElements是个路径元素的列表,常见的路径元素有PathLine(直线) athQuad(赛贝尔二次曲线)、 PathCubic(赛贝尔三次曲线)、PathArc(椭圆上的一段弧)、PathCurve、PathSvg等。路径元素的终点就是整个路径的终点,终点可以和起点重合,如果重合那就表形成闭环。
关于路径上点的坐标:除却PathSbvg之外,都有x、y属性。第一段路径的起点,就是startX,startY.终点以绝对坐标的形式表示,另外还可以通过relativeX、relativeY以相对起点坐标的形式定义终点坐标,同时也可以用绝对坐标和相对坐标的形式混合表示
下面我们来看这几种常用的路径元素,元素路径不可见,但为了使路径可见,我用canvas画出来了。
(1)PathLine
Canvas{ id: lineCanvas width: rootItem.width height: rootItem.height onPaint: { var ctx = getContext("2d") ctx.lineWidth = 2 ctx.strokeStyle = "red" ctx.beginPath() ctx.moveTo(1, 1) ctx.lineTo(width-1, height-1) ctx.stroke() } Rectangle{ id: lineBall width: 32 height: 32 radius: 16 color: "blue" PathAnimation{ id: lineAnim target: lineBall duration: 3000 anchorPoint: "16,16" easing.type: Easing.Linear path: Path{ startX: 16 startY: 16 PathLine{ x: width-16 y: height-16 } } } MouseArea{ anchors.fill: parent onClicked: lineAnim.start() } } }
(2)PathQuad(贝塞尔曲线)。常见的贝塞尔曲线有二次方贝塞尔曲线、三次方曲线、四。。。贝塞尔曲线其实就是一条线,再加上几个控制点,然后再经过一个函数计算得来的。比如二次方贝塞尔曲线,由两个端点+一个控制点+一个函数生成;三次方贝塞尔曲线是由两个端点+两个控制点 +一个函数生成 贝塞尔曲线的起点是用startX.startY表示,用x,y表示终点,用controlX、controlY或者relativeControlX、relativeControlY来表示控制点
下面我们来看一个二次方贝塞尔曲线
Canvas{ //二次方贝塞尔曲线 width: rootItem.width height: rootItem.height //visible: false onPaint: { var ctx = getContext("2d") ctx.lineWidth = 2 ctx.strokeStyle = "red" ctx.beginPath() ctx.moveTo(0, 0)//下面的函数画出二次方的贝塞尔曲线 ctx.quadraticCurveTo(0, height-1, width-1, height-1) ctx.stroke() } Text { anchors.centerIn: parent font.pixelSize: 20 text: "quadratic Bezier curve" } }//二次方贝塞尔曲线 is end
(3)PathCubic,它有两个控制点。直接上代码,在下面的代码中添加了动画处理
Canvas{ //三次方贝塞尔曲线 id: root width: rootItem.width height: rootItem.height //visible: false onPaint: { var ctx = getContext("2d") ctx.lineWidth = 2 ctx.strokeStyle = "red" ctx.beginPath() ctx.moveTo(16,16)//下面的函数画出三次方的贝塞尔曲线 ctx.bezierCurveTo(0, height-1 ,width-1, height/2, width-16, height-16); ctx.stroke() } Text{ anchors.centerIn: parent font.pixelSize: 20 text: "cubic Bezier curve" } Rectangle{ id: ball width: 32 height: 32 radius: 16 color: "blue" PathAnimation{ id: pathAnim target: ball duration: 3000 anchorPoint: "16, 16" easing.type: Easing.InCubic path: Path{ startX: 16 startY: 16 PathCubic{//这是三次方贝塞尔曲线 x: root.width -16 y: root.height-16 control1X: 0 control1Y: height-1 control2X: width-1 control2Y: height/2 } // PathArc{//这是椭圆弧 // x: width /2 // y: height /2 // radiusX: 100 // radiusY: 100 // direction: PathArc.Clockwise // useLargeArc: true // } } } MouseArea{ id: mouseArea anchors.fill: parent onClicked: pathAnim.start() } } }//三次方贝塞尔曲线 is end
(4)PathArc它定义一段椭圆上的一段圆弧,其中起点和终点都一样,另外,椭圆上的两个半轴分别由radiusX、radiusY定义。direction控制圆弧的方向,默认值是PathArc,Clockwise(顺时针),另外还有一个比较使用的属性就是useLargeArc。因为即便是定义了各种属性条件,但是仍有两条弧满足条件-大、小圆弧。那么就可以通过useLargeArc来确定使用大弧还是小弧
直接上弧的代码
Path{ startX: 100 startY: 100 PathArc{ x: 100 y: 100 radiusX: 100 radiusY: 100 direction: PathArc.Clockwise } }
(5)PathCurve,定义一条Catmull-room曲线。上代码,用canvas画出来的
Canvas{ width: rootItem.width height: rootItem.height contextType: "2d" visible: false Path{ id: myPath startX: 4 startY: 100 PathCurve{x:75; y: 75} PathCurve{x:200; y: 150} PathCurve{x: 325; y: 25} PathCurve{x: 294; y: 100} } onPaint: { context.strokeStyle = Qt.rgba(.4, .6 ,.8) context.path = myPath context.stroke() context.sttrokeStyle = "green" context.fillRect(2, 98, 4, 4) context.fillRect(73, 73, 4, 4) context.fillRect(198, 148, 4, 4) context.fillRect(323, 23, 4, 4) context.fillRect(392, 98, 4, 4) } }//room is end
还有其它属性介绍--------------
PathPercent,放在组成路径的元素的后面,比如PathArc后面,指明它前面那部分路径所放置的Item数量占整个路径上所有Item数量的比率。需要注意的是在一个Path中使用PathPercent,PathPercent元素的value值是递增的,某一段路径如果在两个PathPercent之间,那么这段路径上面放置的Item数量占路径上总Item数量的比率,是它后面PathPercent与它前面PathPercent的value的差
还有一个pathView,这个负责的有点多,好不知道怎么用,但下面的范例有点意思,留着以后用吧
import QtQuick 2.2 Rectangle { id: root width: 480 height: 320 color: "black" Component{ id: rectDelegate Item{ id: wrapper z: PathView.zOrder opacity: PathView.itemAlpha scale: PathView.itemScale Rectangle{ width: 100 height: 60 color: Qt.rgba(Math.random(), Math.random(), Math.random(), 1) border.width: 2 border.color: wrapper.PathView.isCurrentItem ? "red" : "lightgray" Text{ anchors.centerIn: parent font.pixelSize: 28 text: index color: Qt.lighter(parent.color, 2) } } } }//rectDelegate is end PathView{ id: pathView anchors.fill: parent interactive: true pathItemCount: 7 preferredHighlightBegin: 0.5 preferredHighlightEnd: 0.5 highlightRangeMode: PathView.StrictlyEnforceRange delegate: rectDelegate model: 15 focus: true Keys.onLeftPressed: decrementCurrentIndex() Keys.onRightPressed: incrementCurrentIndex() path:Path{ startX: 10 startY: 100 PathAttribute{name: "zOrder"; value: 0;} PathAttribute{name: "itemAlpha"; value: 0.1;} PathAttribute{name: "itemScale"; value: 0.6} PathLine{ x: root.width/2 - 40 y: 100 } PathAttribute{name: "zOrder"; value: 10;} PathAttribute{name: "itemAlpha"; value: 0.8;} PathAttribute{name: "itemScale"; value: 1.2} PathLine{ x: root.width/2 - 60 y: 0 } PathAttribute{name: "zOrder"; value: 0;} PathAttribute{name: "itemAlpha"; value: 0.1;} PathAttribute{name: "itemScale"; value: 0.6} } MouseArea{ anchors.fill: parent onWheel: { if(wheel.angleDelta.y > 0) pathView.decrementCurrentIndex() else pathView.incrementCurrentIndex() } } } }