在QML中具有光效的圆形边框

时间:2014-03-24 21:35:24

标签: qt qml

round border with lighting effect

我开始使用QtQuick对Qt进行一些测试。我想知道是否有办法在简单的QML中实现这种边界效果。我已经看到了关于QtQuick3D的一些东西,但听起来太多了......这只是为了在办公室应用程序中获得一些视觉效果。这个应用程序很可能是在低端桌面上运行的,我不想让这些效果受到任何性能损失。但是请更正,如果我错误地认为3D太多了。

直截了当的替代方案似乎是BorderImage对象,但我想确保在普通QML中没有办法(即没有外部图像)。

我感谢任何帮助。

2 个答案:

答案 0 :(得分:3)

我完全没有效果地重现完全相同的效果,只有Gradient:

import QtQuick 2.0;

Rectangle {
    width: 640;
    height: 95;
    color: "black";

    Item {
        id: fakeRect;
        height: 80;
        width: 480;
        anchors.centerIn: parent;

        property alias color      : fakeBackground.color;
        property int   borderSize : 4;

        Rectangle {
            id: fakeBorder;
            radius: Math.min (width, height) * 0.5;
            antialiasing: true;
            gradient: Gradient {
                GradientStop { position: 0.0; color: Qt.lighter (fakeRect.color, 1.65); }
                GradientStop { position: 1.0; color: Qt.darker  (fakeRect.color, 1.65); }
            }
            anchors.fill: parent;

            Rectangle {
                id: fakeBackground;
                color: "#5A5A5A";
                radius: Math.min (width, height) * 0.5;
                antialiasing: true;
                anchors {
                    fill: parent;
                    margins: fakeRect.borderSize;
                }
            }
        }
    }
}

实际上很简单,只是不要使用Rectangle.border,用自定义组件模拟它!

答案 1 :(得分:2)

也许您尝试使用ShaderEfect实现此功能? 这段代码效率不高,但应该在今天的低性能图形卡(OpenGL 3+)和Qt5.2(带有一些旁路的Qt 5.0)上按预期工作:

ShaderEffect {
    x:50
    y:50
    width: 500
    height: 100

    property color color: "grey"
    property vector2d size: Qt.vector2d(width,height)
    property real lightsize: 5
    property real round:  50

    vertexShader: "
        uniform highp mat4 qt_Matrix;
        attribute highp vec4 qt_Vertex;
        uniform highp vec2 size;
        varying highp vec2 coord;
        void main() {
            coord = qt_Vertex.xy;
            gl_Position = qt_Matrix * qt_Vertex;
        }"
    fragmentShader: "
        varying highp vec2 coord;
        uniform highp vec2 size;
        uniform lowp vec4 color;
        uniform lowp float qt_Opacity;
        uniform lowp float lightsize;
        uniform lowp float round;
        void main() {
            float dx=0.0f;
            float dy=0.0f;
            if( coord.x < round )
                dx = coord.x-round;
            else if( coord.x > (size.x - round) )
                dx = round - (size.x - coord.x);
            if( coord.y < round )
                dy = coord.y-round;
            else if( coord.y > (size.y - round) )
                dy = round-(size.y - coord.y);
            float distance= sqrt(dx*dx+dy*dy);
            float ilumination = dot(vec2(dx, dy)/distance,vec2(-0.5f,-0.5f)) * 0.5 * smoothstep( lightsize, 0.0f , abs(distance-(round-lightsize*0.5)) );
            lowp vec4 insidecolor = (vec4(ilumination, ilumination , ilumination,0.0f)+color) * smoothstep( round, round-2.0f, distance);
            gl_FragColor =  insidecolor * qt_Opacity;
        }"

}

Rounded Box