한국어
Qt
 

ShaderEffect을 이용하면 다양한 그래픽효과를 구현할 수 있다. 이를 이용해서 버튼의 클릭 효과를 구현해본다.

ShaderEffectQmlButton.gif

 

MyButton.qml

import QtQuick 2.2

Item{

    signal clicked()
    signal pressed()

    property alias radius: base.radius

    Rectangle{
        id: base

        radius: 10
        anchors.fill: parent
        color: "#10000000"
    }

    ShaderEffect {
        id: shaderEffect1
        opacity: 1
        anchors.fill: parent

        property variant source: effectSource

        ShaderEffectSource {
            id: effectSource
            sourceItem: base
            hideSource: true
        }

        property point normTouchPos
        property real widthToHeightRatio: height / width
        // animated uniform property
        property real spread: 0

        ParallelAnimation {
            id: touchStartAnimation
            UniformAnimator {
                uniform: "spread";
                target: shaderEffect1
                from: 0; to: 1
                duration: 300
                easing.type: Easing.InQuad
            }
            onStopped: {
                // animation stopped
                if(!touch.pressed){
                    if(shaderEffect1.spread != 0)
                        shaderEffect1.spread = 0
                }
            }
        }

        fragmentShader: "
            uniform sampler2D source;
            varying mediump vec2 qt_TexCoord0;
            uniform lowp float qt_Opacity;
            uniform mediump vec2 normTouchPos;
            uniform mediump float widthToHeightRatio;
            uniform mediump float spread;

            void main() {
                mediump float radius = (0.5 + abs(0.5 - normTouchPos.x)) * 1.0 * spread;
                mediump vec2 circleCenter =
                    normTouchPos + (vec2(0.5) - normTouchPos) * radius * 2.0;

                mediump float circleX = (qt_TexCoord0.x - circleCenter.x);
                mediump float circleY = (qt_TexCoord0.y - circleCenter.y) * widthToHeightRatio;

                highp vec4 color = texture2D(source, qt_TexCoord0);

                lowp vec4 tapOverlay =
                    color * step(circleX*circleX + circleY*circleY, radius*radius);
                gl_FragColor = (color + tapOverlay) * qt_Opacity;
            }
        "

        function touchStart(x, y) {
            normTouchPos = Qt.point(x / width, y / height)
            touchStartAnimation.start()
        }

        function touchStop() {
            touchStartAnimation.stop()
        }
    }

    MouseArea{
        id: touch
        anchors.fill: parent
        onPressed: {
            shaderEffect1.touchStop()
            shaderEffect1.touchStart(mouseX, mouseY)
        }
        onClicked: {
            parent.clicked()
            shaderEffect1.spread = 0
        }
        onExited: {
            shaderEffect1.spread = 0
        }
    }
}

 

다음은 구현된 MyButton을 사용하는 방법이다.

main.qml

import QtQuick 2.2
import QtQuick.Window 2.2
import QtQuick.Layouts 1.3

Window {
    visible: true
    width: 320
    height: 240
    title: qsTr("ShaderEffect Custom Button")

    ColumnLayout{
        anchors.centerIn: parent
        spacing: 10

        MyButton{
            width: 100
            height: 100
            radius: 50
            Layout.alignment: Qt.AlignHCenter

            Text {
                id: button0_text
                anchors.centerIn: parent
                text: qsTr("Hello")
                font.pixelSize: 15
            }

            onClicked: {
                if(button0_text.text == "Hello")
                    button0_text.text = "OK"
                else{
                    button0_text.text = "Hello"
                }
            }
        }

        MyButton{
            width: 100
            height: 50
            Layout.alignment: Qt.AlignHCenter

            Text {
                id: button1_text
                anchors.centerIn: parent
                text: qsTr("MyButton")
                font.bold: true
            }

            onClicked: {
                if(button1_text.text == "MyButton")
                    button1_text.text = "Makersweb.net"
                else{
                    button1_text.text = "MyButton"
                }
            }
        }
    }
}

 

번호 제목 글쓴이 날짜 조회 수
공지 Qt프로그래밍(QtQuick) Beginner를 위한 글 읽는 순서 운영자 2019.01.05 91487
80 QThread 소개 및 예제 makersweb 2019.12.25 21502
79 ApplicationWindow 와 메뉴바(MenuBar)구성 file makersweb 2020.01.04 2275
78 Qt 멀티 스레드 프로그래밍 시 유의해야 할 몇 가지 makersweb 2020.01.13 5956
77 Qt로 XML 파싱 : Qt 6에서 업데이트된 (Parsing XML with Qt: Updates for Qt 6) [1] j2doll 2020.01.16 1732
76 2020년에 변경되는 Qt 오퍼 (Qt offering changes 2020) [2] j2doll 2020.01.31 1439
75 QOpenGLWidget 을 투명하게 적용 file makersweb 2020.02.05 1983
74 라즈베리파이4에 대한 Qt 5.14.1 크로스컴파일 [1] file makersweb 2020.02.12 5290
73 QLabel의 텍스트 색과 배경색을 변경 makersweb 2020.02.25 8061
72 Qt로 작성된 안드로이드 APP에 Splash Screen을 추가 file makersweb 2020.03.10 1612
71 컨테이너 클래스 - QVector makersweb 2020.03.17 3646
70 콘솔에서 사용자 입력받기 file makersweb 2020.03.22 52810
69 Qt 5.15 및 Qt 6의 출시 일정 makersweb 2020.04.09 1612
68 재진입(Reentrancy) 및 스레드 안전성(Thread-Safety) makersweb 2020.04.19 1840
67 Qt기반의 서버와 클라이언트간 SOAP(Simple Object Access Protocol) file makersweb 2020.05.11 1838
» ShaderEffect QML Type을 이용한 버튼 클릭 효과 file makersweb 2020.05.22 1940
65 Embedded Linux 에서 Qt 및 Graphics Stack file 운영자 2020.05.27 1396
64 Qt MQTT 에 대해서 file makersweb 2020.06.02 1712
63 최초의 Qt 6.0 스냅샷 제공 (First Qt 6.0 Snapshot Available) j2doll 2020.06.21 1339
62 Qt로 데이터를 직렬화(serialization)하는 방법 makersweb 2020.08.04 2990
61 UI 폼(Form)작성 시 탭 순서(Tab Order) 설정 file makersweb 2020.08.24 4158