如何创建不规则形状的qml组件
-
- QML组件是无窗口的,无法用widget那样用setMask设置png的遮罩图层;
- Rectangle的clip属性设置为true后,其遮罩区域事实上是矩形的,设置了radius无效。例如:
@Rectangle{
id: root
width: 500
height: 500
radius: width/2
color: 'black'
clip: trueRectangle{ height: parent.height/3 width: parent.width anchors.verticalCenter: parent.verticalCenter color: 'lightblue' }
}@
预想的目标:一个黑色的圆,中间一个淡蓝色的条带,中间的条带是限制在圆里面的;
而实际上:中间的条带是突出到圆外的我该如何实现我想要的目的
-
-用 Image 或者 Canvas 自己画一个吧,手册里没有讲到任意形状,估计是保留着以后可能会实现。-
@
Rectangle{
id: root
width: 500
height: 500
radius: width/2
color: 'black'
Item {
height: parent.height/3
width: parent.width
anchors.verticalCenter: parent.verticalCenter
clip: true
Rectangle{
color: 'lightblue'
anchors.centerIn: parent
width: parent.width
height: width
radius: width / 2
}
}
}
@ -
思路不错,多谢。我稍微调整了一下代码可跑:
@Rectangle{
id: root
width: 500
height: 500
radius: width/2
color: 'black'Rectangle{ anchors.verticalCenter: parent.verticalCenter height: parent.height/3 width: parent.width clip: true Rectangle{ width: root.width; height:root.height radius: width/2 anchors.centerIn: parent color: 'lightblue' } }
}
@
我查了资料,说是因为性能考虑,clip只支持矩形(qt 5.3前)。
这有时的确是诸多不便,希望以后会支持吧。 -
Canvas里面的例子就能够满足你的需求。
除此之外,还可以设置Item::transform想办法让边界变成圆形。 -
关于不规则控件,实时上有两点需要处理
(1)外观:这个可以用png或shader实现
(2)事件区域限制:这个我编写了个ImageMouseArea,希望对大家有用
@import QtQuick 2.0/**
\title 图像鼠标区域(可获取点击点的像素是否是透明的)
\qml
Image{
source: 'pentagon.png'
anchors.centerIn: parent;
ImageMouseArea{
imageUrl: 'pentagon.png'
anchors.fill: parent
onPressed: {
if (!isCurrentPointTransparent())
console.log('pressed')
}
}
}
*/
MouseArea {
anchors.fill: parent// png图片 property alias imageUrl: canvas.imageUrl // 当前点是否是透明的,请在鼠标事件中调用 function isCurrentPointTransparent(){ return canvas.isTransparent(mouseX, mouseY); } // 用canvas保存图像信息,并用于点击检测 Canvas { id: canvas; anchors.fill: parent contextType: "2d"; visible: false; z: 2; property string imageUrl: 'roundmenu.png'; function isTransparent(x, y){ if (imageUrl == null) return true; else{ var p = context.getImageData(x, y, 1, 1).data; var r = p[0]; var g = p[1]; var b = p[2]; var a = p[3]; console.debug("(" + x + "," + y + "): "+ r + "," + g + ',' + b + ',' + a); return (a==0); } } onPaint: { if(imageUrl != null){ context.drawImage(imageUrl, 0, 0); } } }
}
@