QML学习笔记——控件-自定义方向button
写在前面
- 之前用的方向键按钮都是矩形做的,后来UI给了一张图,照着图片改造了一番,看起来更像方向盘了= =。
环境
- Qt 5.9.3 + MinGW
- window 10
思路流程
- 首先最重要的当然是图啦,按钮的UI显示都是贴图完成的。
- 区域划分,按照按钮区域对图片区域进行划分,up,down,left,right,center,一共五个按键。
- State,利用State在控件不同的状态下绑定不同的贴图。
- signal,通过不同的信号,将各个按钮的单击事件传递出去。
区域划分
- 如上图,上下左右各占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信号。
小结
- 后续可以增加长按,双击等事件。
- 这个主要还是依赖图片来显示,也可以改为canvas进行绘制。
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。