Qt 5.4 QML 事件处理 鼠标、键盘、定时器
MouseArea
MouseArea
对象可以附加到一个 item 上供 item 处理鼠标事件,它本身是一个不可见的 item 。在其内部,可以直接引用它所附着的对象的属性和方法。你可以将 MouseArea 理解为它所附着的 item 的代理。
MouseArea 有很多属性
enabled
用来控制是否处理鼠标事件,默认值是 true ,如果你设置为 false ,那么它所代理的 item 就会无视鼠标事件。
acceptedButtons
设定接收拿些个鼠标按键产生的事件(左键、右键、中键).
示例代码 acceptedButtons: Qt.LeftButton | Qt.RightButton;
表示处理鼠标左键和右键。
anchors
作为一个 item , MouseArea 也拥有 anchors 属性,你可以使用它来描述有效的鼠标区域。示例代码 "anchors.fill: parent;" 表示整个矩形区域都接受鼠标事件。
MouseArea 还有很多其他属性,如 hoverEnabled , pressed 等等,请参考 Qt 帮助文档。
示例代码中,在 MouseArea 对象内使用了 onClicked 和 onDoubleClicked 两个信号处理器,他们对应 MouseArea 的 onClicked
和 onDoubleClicked
信号, MouseArea 还有很多其他的信号,如 onPressed / onReleased / onEntered / onExited / onPressAndHold
等等,从名字上就可以看到这些信号的含义。
onClicked 信号的参数是 MouseEvent
类型,名为 mouse
,所以你可以在信号处理器中直接使用 mouse 来查询鼠标事件的详情。比如哪个 button 按下,正如示例代码中看到的那样, MouseEvent 的 button 属性保存了被按下的鼠标按键标记, x , y 属性保存鼠标指针位置。 还有一个比较重要的属性 accepted ,如果你处理鼠标事件后不想这个事件再往下传递,就置其值为 true 。
onDoubleClicked
信号代表双击事件,其参数也是 MouseEvent 类型,示例中双击鼠标,矩形颜色变为灰色。
简单的鼠标事件处理就这些内容,根据你应用的需要,可能你还会处理 onPressed / onReleased / onEntered
等等信号。
示例代码:
import QtQuick 2.0
import QtQuick.Controls 1.1
Rectangle {
width: 320;
height: 240;
MouseArea {
anchors.fill: parent;
acceptedButtons: Qt.LeftButton | Qt.RightButton;//处理鼠标左键和右键。
onClicked: {
if(mouse.button == Qt.RightButton){ //使用 mouse 来查询鼠标事件的详情
Qt.quit();
}
else if(mouse.button == Qt.LeftButton){
color = Qt.rgba((mouse.x % 255) / 255.0 , (mouse.y % 255) / 255.0, 0.6, 1.0);//根据鼠标位置改变颜色
}
}
onDoubleClicked: {
color = "gray";
}
}
}
键盘事件处理
手机上键盘事件最重要的为 BACK
按键处理
会动的文本实例:
import QtQuick 2.0
import QtQuick.Controls 1.1
Rectangle {
width: 320;
height: 480;
color: "gray";
focus: true;
Keys.enabled: true;
Keys.onEscapePressed: {
Qt.quit();
}
Keys.forwardTo: [moveText, likeQt];
Text {
id: moveText;
x: 20;
y: 20;
width: 200;
height: 30;
text: "Moving Text";
color: "blue";
//focus: true;
font { bold: true; pixelSize: 24;}
Keys.enabled: true;
Keys.onPressed: {
switch(event.key){
case Qt.Key_Left:
x -= 10;
break;
case Qt.Key_Right:
x += 10;
break;
case Qt.Key_Down:
y += 10;
break;
case Qt.Key_Up:
y -= 10;
break;
default:
return;
}
event.accepted = true;//每次按键结束后禁止信号传递
}
}
CheckBox {
id: likeQt;
text: "Like Qt Quick";
anchors.left: parent.left;
anchors.leftMargin: 10;
anchors.bottom: parent.bottom;
anchors.bottomMargin: 10;
z: 1;
}
}
说明:
Keys
对象是 Qt Quick 提供的,专门供 Item 处理按键事件的对象。
它定义了很多针对特定按键的信号,比如 onReturnPressed / onEscapePressed / onDownPressed / onDigit0Pressed / onBackPressed 等等;它还定义了更为普通的 onPressed 和 onReleased 信号,一般地,你可以使用这两个信号来处理大部分按键(请对照 Qt C++ 中的 keyPressEvent 和 keyReleaseEvent 来理解),它们有一个名字是 event 的 KeyEvent 参数,包含了按键的详细信息。
KeyEvent 代表一个按键事件,如果一个按键被处理, event.accepted 应该被设置为 true 以免它被继续传递;要是你不设置它,那它可能会继续传递给其他的 item ,出现一些奇奇怪怪的问题。
Keys 有三个属性。
- enabled 属性控制是否处理按键。
- forwardTo 属性是列表类型.
它表示传递按键事件给列表内的对象,如果某个对象 accept 了某个按键,那位列其后的对象就不会收到该按键事件。示例代码 "Keys.forwardTo: [moveText, likeQt];" 表明转发按键给 id 为 moveText 的 Text 对象和 id 为 likeQt 的 CheckBox 对象。 moveText 在前面,如果它消耗掉某个键, likeQt 就收不到了。你可以修改 Text 对象的 Keys.onPressed 附加信号处理器,在 case 列表中添加 Qt.Key_Space 看看效果。
- priority 属性允许你设置 Keys 附加属性的优先级.
该属性有两种,在 Item 之前处理按键,这是默认行为,在 Item 之后处理按键。你可以对照着 Qt C++ 的 keyPressEvent() 函数来理解,如果你在派生类中重载了 keyPressEvent() 方法,那么你可以在重载方法的一开始调用父类的 keyPressEvent() ,也可以在你处理完感兴趣的事件后再调用父类的 keyPressEvent() 。这期间的逻辑关系也很简单,假如 Keys 先处理按键,如它吃掉了某个键,它所依附的 Item 对象就收不到这个按键了;反之亦然。
Qt Quick 提供的一些元素本身会处理按键,比如示例中的 CheckBox ,它响应空格键来选中或取消选中。而我们不需要给它附加 Keys 对象来再次处理按键事件。当然,如果你想改变它的按键响应逻辑,可以这么做,在解释 priority 属性时已经提到这点。
最后还有一点要说明的是,如果你想某个元素处理按键,需要把焦点给它,这通过 Item 的 focus 属性来控制,置 true 即可。
Timer 定时器
在 QML 中, Timer 代表定时器,使用起来也很简单,响应其 onTriggered() 信号即可,它也就这么一个有用的信号。
另外它还有几个属性要说明一下:
interval
指定定时周期,单位是毫秒,默认值是 1000 毫秒;
repeat
设定定时器是周期性触发还是一次性触发,默认是一次性的(好像和 QTimer 不一样嗳);
running
设置为 true 定时器就开始工作,设置为 false 就歇菜,默认是 false ;
triggeredOnStart 属性
怎么说呢, Qt 总是对我们这么好都有点儿那啥不好意思了,这个属性是考虑到有些同志的特殊需求,本来定时器启动后要等待设定的间隔才触发,如果你设置这个属性为 true ,那定时器开始执行时立马先触发一次,默认值是 false 。
Timer 还有 start()
/ stop()
/ restart()
三个方法可以调用,它们会影响 running 属性
代码举例:
import QtQuick 2.3
import QtQuick.Controls 1.2
Rectangle {
// property alias mouseArea: mouseArea
width: 360
height: 360
QtObject { //用于逻辑计算,不会在页面中显示。这里如果用别的代替(如 Item,Component),则不能新定义属性类型
id: attrs
property int counter //定义一个 int 型变量,counter
Component.onCompleted: {
attrs.counter = 10 //组件初始化
}
}
Text {
id: countshow
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
anchors.topMargin: 35
text: "Hello World"
}
Timer {
id: countdown
interval: 1000 //执行周期,单位为毫秒
repeat: true //周期性触发,默认为 false,若循环触发需要改为 true
triggeredOnStart: true //第一次启动即立即触发一次。若为 false,则第一次启动先走周期
onTriggered: { //启动触发器(onTriggered 信号处理器)
countshow.text = attrs.counter
attrs.counter -= 1 //执行递减
if(attrs.counter < 0)
{
countdown.stop()//停止计时器
countshow.text = "Time OVER!"
attrs.counter = 10//允许再次启动
}
}
}
Rectangle {
width: 100
height: 35
color:"blue"
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
anchors.bottomMargin: 20
MouseArea {
id: mouseArea
anchors.fill: parent
onPressed: {
countdown.start() //启动计时器
}
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: Qt 5.4 QML Item 类
下一篇: Covenant 利用分析
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论