Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. International
  3. Chinese
  4. 如何创建不规则形状的qml组件
Forum Updated to NodeBB v4.3 + New Features

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

Scheduled Pinned Locked Moved Chinese
5 Posts 3 Posters 8.1k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    surfsky
    wrote on last edited by
    #1
    • 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'
    }
    

    }@

    预想的目标:一个黑色的圆,中间一个淡蓝色的条带,中间的条带是限制在圆里面的;
    而实际上:中间的条带是突出到圆外的

    我该如何实现我想要的目的

    1 Reply Last reply
    0
    • L Offline
      L Offline
      lane
      wrote on last edited by
      #2

      -用 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
      }
      }
      }
      @

      1 Reply Last reply
      0
      • S Offline
        S Offline
        surfsky
        wrote on last edited by
        #3

        思路不错,多谢。我稍微调整了一下代码可跑:
        @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前)。
        这有时的确是诸多不便,希望以后会支持吧。

        1 Reply Last reply
        0
        • J Offline
          J Offline
          jiangcaiyang
          wrote on last edited by
          #4

          Canvas里面的例子就能够满足你的需求。
          除此之外,还可以设置Item::transform想办法让边界变成圆形。

          1 Reply Last reply
          0
          • S Offline
            S Offline
            surfsky
            wrote on last edited by
            #5

            关于不规则控件,实时上有两点需要处理
            (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);
                    }
                }
            }
            

            }
            @

            1 Reply Last reply
            0

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved