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信号。

小结

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值