代码之家  ›  专栏  ›  技术社区  ›  brandon

QML-半径为的矩形上的LinearGradient?

  •  2
  • brandon  · 技术社区  · 8 年前

    我有一个带圆角(半径)的简单矩形,但希望为其背景色应用渐变。

    Rectangle {
        id: rect
        width: 200
        height: 200
    
        radius: 20
    
        LinearGradient {
            anchors.fill: parent
            start: Qt.point(0,parent.height/2)
            end: Qt.point(parent.width,parent.height/2)
            gradient: Gradient {
                GradientStop { position: 0.0; color: "red" }
                GradientStop { position: 1.0; color: "green" }
            }
        }
    }
    

    我在想一个不透明的面具会有用吗?不过,我试过用一个也没用。我想知道我是否遗漏了什么,或者解决方案是否更复杂。

    3 回复  |  直到 8 年前
        1
  •  3
  •   jpnurmi    8 年前

    Qt图形效果很强大,但这种能力是有代价的。只要可能,最好使用Qt Quick core原语。也许这只是一个简化的测试用例,而现实生活中的用例则要复杂得多,但所显示的测试用例是可以实现的,只需简单而轻的圆角、旋转和渐变填充 Rectangle :

    Rectangle {
        id: rect
        width: 200
        height: 200
    
        radius: 20
        rotation: -90
    
        gradient: Gradient {
            GradientStop { position: 0.0; color: "red" }
            GradientStop { position: 1.0; color: "green" }
        }
    }
    

    为了支持性能声明,让我们看看用 QML bench 基准测试工具。我们正在对一个使用 OpacityMask LinearGradient 用一个简单的 长方形 Gradient . 这些基准测试是在一台破旧的MacBook Air(Intel Core i5-4260U、Intel HD 5000、macOS 10.13)上使用最新的Qt 5.10.1版本运行的。

    LinearGradient + OpacityMask

    ID:          
    OS:          macOS High Sierra (10.13)
    QPA:         cocoa
    GL_VENDOR:   Intel Inc.
    GL_RENDERER: Intel HD Graphics 5000 OpenGL Engine
    GL_VERSION:  2.1 INTEL-10.30.14
    running: lineargradient_opacitymask.qml
        11 frames
        11 frames
        11 frames
        11 frames
        11 frames
        Average: 11  frames;; MedianAll=11; StdDev=0, CoV=0
    All done...
    

    Rectangle::gradient

    ID:          
    OS:          macOS High Sierra (10.13)
    QPA:         cocoa
    GL_VENDOR:   Intel Inc.
    GL_RENDERER: Intel HD Graphics 5000 OpenGL Engine
    GL_VERSION:  2.1 INTEL-10.30.14
    running: rect_gradient.qml
        332 frames
        331 frames
        334 frames
        313 frames
        331 frames
        Average: 328.2  frames;; MedianAll=331; StdDev=8.58487, CoV=0.0261574
    All done...
    
        2
  •  3
  •   Striezel EDi    8 年前

    设置LinearGradient的源属性,可以解决此问题:

    Rectangle {
    
        id: rect
        width: 200
        height: 200
        radius: 20
    
        LinearGradient {
            anchors.fill: parent
            source: rect
            start: Qt.point(0,parent.height/2)
            end: Qt.point(parent.width,parent.height/2)
            gradient: Gradient {
                GradientStop { position: 0.0; color: "red" }
                GradientStop { position: 1.0; color: "green" }
            }
        }
    }
    
        3
  •  1
  •   dtech    8 年前

    嗯,不透明度遮罩应该可以工作,但是你必须隐藏源,使圆角可见,否则它们将从后面显示。。。

      Rectangle {
        id: rect
        width: 200
        height: 200    
        // radius: 20 - redundant
        visible: false // hide it!!!
    
        LinearGradient {
          anchors.fill: parent
          start: Qt.point(0,parent.height/2)
          end: Qt.point(parent.width,parent.height/2)
          gradient: Gradient {
            GradientStop { position: 0.0; color: "red" }
            GradientStop { position: 1.0; color: "green" }
          }
        }
      }
    
      OpacityMask {
        anchors.fill: rect
        source: rect
        maskSource: Rectangle {
          width: 200
          height: 200
          radius: 20
        }
      }