한국어
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 87719
179 Qbs 프로젝트를 정의하기 위해 사용되는 몇가지 중요한 아이템들 file makersweb 2019.10.13 363
178 Qt 6.4에 추가될 Qt Quick 3D Physics file makersweb 2022.08.07 436
177 HTTPS URL을 연결할 때 SslHandshakeFailedError 오류 makersweb 2022.07.31 460
176 Qt 응용프로그램에 Web 구성 요소를 표시 with Servo file makersweb 2024.04.27 460
175 Qt Android 앱에 AdMob 배너달기 file makersweb 2021.12.04 483
174 그래픽 소프트웨어에서 디자인 내보내기 (Exporting Designs from Graphics Software) j2doll 2020.12.25 499
173 Binding 타입으로 객체 속성 간 묶기 makersweb 2022.03.04 518
172 Qt Quick Controls 2에 네이티브 데스크탑 스타일 추가 file makersweb 2020.11.23 577
171 성능 고려 및 제안 사항 makersweb 2022.03.07 591
170 VirtualKeyboard 스타일 커스터 마이징 makersweb 2022.03.13 596
169 안드로이드용 Qt 6.2 makersweb 2021.10.02 602
168 앱을 종료할 때 QML 바인딩 오류를 피하는 방법 makersweb 2021.08.08 614
167 Qt Safe Renderer 개요 file makersweb 2022.09.08 627
166 응용프로그램 자동실행 설정 (on Windows) makersweb 2021.05.08 656
165 최초의 Qt 6.0 스냅샷 제공 (First Qt 6.0 Snapshot Available) j2doll 2020.06.21 679
164 Qt Marketplace 발표 makersweb 2019.12.02 683
163 QML과 코루틴(Coroutines) makersweb 2020.11.03 688
162 clazy 로 13개의 시그널, 슬롯 오류 해결 makersweb 2022.08.23 689
161 QProcess 보안 권고 리뷰 file makersweb 2022.09.18 693
160 Embedded Linux 에서 Qt 및 Graphics Stack file 운영자 2020.05.27 720