QML學習筆記——控件-自定義方向button

寫在前面

  • 之前用的方向鍵按鈕都是矩形做的,後來UI給了一張圖,照着圖片改造了一番,看起來更像方向盤了= =。
Normal

環境

  • Qt 5.9.3 + MinGW
  • window 10

思路流程

  • 首先最重要的當然是圖啦,按鈕的UI顯示都是貼圖完成的。
  • 區域劃分,按照按鈕區域對圖片區域進行劃分,up,down,left,right,center,一共五個按鍵。
  • State,利用State在控件不同的狀態下綁定不同的貼圖。
  • signal,通過不同的信號,將各個按鈕的單擊事件傳遞出去。

區域劃分

o(╯□╰)o

  • 如上圖,上下左右各佔90°角,可以利用正弦和餘弦值來判斷區域。

Demo.qml

import QtQuick 2.0

Item {
    id:root;
    property int d: 100;           		 //直徑
    property int r: d/2;    				//半徑
    property double c_scale: 0.35;  //中心圓佔比

    signal clickUp();
    signal clickDown();
    signal clickLeft();
    signal clickRight();
    signal clickCenter();

    width: d;
    height: d;

    Image {
        id: black_img;
        anchors.fill: parent;
        source: "qrc:/image/img/Normal.png"

        //按鈕狀態
        states: [
            State {
                name: "upStates"
                PropertyChanges {
                    target: black_img
                    source:"qrc:/image/img/Up.png"
                }
            },//注意這裏的逗號
            State {
                name: "downStates"
                PropertyChanges {
                    target: black_img
                    source:"qrc:/image/img/Down.png"
                }
            },
            State {
                name: "leftStates"
                PropertyChanges {
                    target: black_img
                    source:"qrc:/image/img/Left.png"
                }
            },
            State {
                name: "rightStates"
                PropertyChanges {
                    target: black_img
                    source:"qrc:/image/img/Right.png"
                }
            },
            State {
                name: "centerStates"
                PropertyChanges {
                    target: black_img
                    source:"qrc:/image/img/Center.png"
                }
            },
            State {
                name: "normalStates"
                PropertyChanges {
                    target: black_img
                    source:"qrc:/image/img/Normal.png"
                }
            }
        ]

        //計算鼠標事件
        MouseArea{
            id:m_mouse
            anchors.fill: parent;
            onPressed: {
                console.log(mouseX,mouseY);
                var _x = mouseX-r;
                var _y = r-mouseY;
                var _z = Math.sqrt(Math.pow(Math.abs(_x),2)+Math.pow(Math.abs(_y),2));
                console.log(_x,_y,_z);
                if(_z<r)
                {
                    //console.log(Math.sin(Math.PI/4))
                    if(_z<c_scale*r)
                    {
                        black_img.state="centerStates";
                        clickCenter();
                    }
                    else if(_y/_z >0.707)
                    {
                        black_img.state="upStates";
                        clickUp();
                    }
                    else if(_y/_z <-0.707)
                    {
                        black_img.state="downStates";
                        clickDown();
                    }
                    else if(_x/_z <-0.707)
                    {
                        black_img.state="leftStates";
                        clickLeft();
                    }
                    else if(_x/_z >0.707)
                    {
                        black_img.state="rightStates";
                        clickRight();
                    }
                }
            }
            onReleased: {
                black_img.state="normalStates";
            }
        }
    }
}

  • states定義6個按鈕狀態(5個按鈕按下狀態和1個彈起狀態)。
  • MouseAread中鼠標座標是以區域左上角爲原點,先換算成以圓心爲原點的座標,再求出鼠標到圓心的距離。(r爲外圓半徑)。

var _x = mouseX-r;
var _y = r-mouseY;
var _z = Math.sqrt(Math.pow(Math.abs(_x),2)+Math.pow(Math.abs(_y),2));

  • c_scale是內圓半徑比外圓半徑。
  • 0.707爲45°的正餘弦。
  • 根據鼠標點擊位置的不同,修改black_img的狀態,並觸發不同的signal信號。

小結

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章