如何创建不规则形状的qml组件



    • QML组件是无窗口的,无法用widget那样用setMask设置png的遮罩图层;
    • Rectangle的clip属性设置为true后,其遮罩区域事实上是矩形的,设置了radius无效。例如:

    @Rectangle{
    id: root
    width: 500
    height: 500
    radius: width/2
    color: 'black'
    clip: true

    Rectangle{
        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);
            }
        }
    }
    

    }
    @


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.