• Qt Quick 事件处理之鼠标、键盘、定时


    一、鼠标事件

    MouseArea 对象可以附加到一个 item 上供 item 处理鼠标事件,它本身是一个不可见的 item 。在其内部,可以直接引用它所附着的对象的属性和方法。你可以将 MouseArea 理解为它所附着的 item 的代理。

    MouseArea 有很多属性, enabled 用来控制是否处理鼠标事件,默认值是 true ,如果你设置为 false ,那么它所代理的 item 就会无视鼠标事件。 acceptedButtons 属性设定接收哪些鼠标按键产生的事件(左键、右键、中键),示例代码acceptedButtons: Qt.LeftButton | Qt.RightButton;表示处理鼠标左键和右键。

    作为一个 item , MouseArea 也拥有 anchors 属性,你可以使用它来描述有效的鼠标区域。示例代码 anchors.fill: parent;表示整个矩形区域都接受鼠标事件。

    MouseArea 还有很多其他属性,如 hoverEnabled , pressed 等等,请参考 Qt 帮助文档。


    变色矩形示例

    看一个简单的处理鼠标事件的例子,先看代码:

    import QtQuick 2.2
    import QtQuick.Controls 1.1
     
    Rectangle {
         320;
        height: 240;
        
        MouseArea {
            anchors.fill: parent;
            acceptedButtons: Qt.LeftButton | Qt.RightButton;
            onClicked: {
                if(mouse.button == Qt.RightButton){
                    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";
            }
        }
    }
    

    上面代码中,在 MouseArea 对象内使用了onClickedonDoubleClicked两个信号处理程序,他们对应 MouseArea 的onClickedonDoubleClicked信号。另外,如果你点一下鼠标右键,程序会退出。


    使用 "qmlscene handle_mouse.qml" 命令,可以看到运行效果。上面的代码仅仅是绘制一个矩形,当鼠标左键按下时改变矩形区域的颜色,鼠标右键按下时退出应用。下面是刚运行时的效果图:

    img


    下面是点击鼠标左键后的效果图:

    img


    二、键盘事件

    Keys 对象是 Qt Quick 提供的,专门供 Item 处理按键事件的对象。它定义了很多针对特定按键的信号,比如onReturnPressed / onEscapePressed / onDownPressed / onDigit0Pressed / onBackPressed等等;它还定义了更为普通的onPressedonReleased信号,一般地,你可以使用这两个信号来处理大部分按键。

    KeyEvent 代表一个按键事件,如果一个按键被处理,event.accepted应该被设置为 true 以免它被继续传递;要是你不设置它,那它可能会继续传递给其他的 item,出现一些奇奇怪怪的问题。

    Keys 有三个属性:

    • enabled 属性控制是否处理按键。

    • forwardTo 属性是列表类型,它表示传递按键事件给列表内的对象,如果某个对象 accept 了某个按键,那位列其后的对象就不会收到该按键事件。

      示例代码:Keys.forwardTo: [moveText, likeQt];,表明转发按键给 id 为 moveText 的 Text 对象和 id 为 likeQt 的 CheckBox 对象。 moveText 在前面,如果它消耗掉某个键, likeQt 就收不到了。

    • priority 属性允许你设置 Keys 附加属性的优先级,有两种,在 Item 之前处理按键,这是默认行为,在 Item 之后处理按键。


    Qt Quick 提供的一些元素本身会处理按键,比如 CheckBox ,它响应空格键来选中或取消选中,而我们不需要给它附加 Keys 对象来再次处理按键事件。

    最后还有一点要说明的是,如果你想某个元素处理按键,需要把焦点给它,这通过 Item 的 focus 属性来控制,置 true 即可。


    简单示例

    下面来看一个示例代码:

    import QtQuick 2.2
    import QtQuick.Controls 1.1
     
    Rectangle {
         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;
             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;
        }
    }
    

    这个示例通过上下左右四个按键移动一个文本串,空格键选中复选框, Esc 键退出应用。下面是初始运行效果图:

    img


    下面是我按了几次方向键,按了空格键后的效果图:

    img


    三、定时器

    在 QML 中, Timer 代表定时器,使用起来也很简单,响应其onTriggered()信号即可,它也就这么一个有用的信号。另外它还有几个属性要说明一下:

    • interval 指定定时周期,单位是毫秒,默认值是 1000 毫秒;
    • repeat 设定定时器是周期性触发还是一次性触发,默认是一次性的;
    • running 属性,设置为 true 定时器就开始工作,设置为 false 就歇菜,默认是 false ;
    • triggeredOnStart 属性,这个属性是考虑到有些人的特殊需求,本来定时器启动后要等待设定的间隔才触发,如果你设置这个属性为 true ,那定时器开始执行时立马先触发一次,默认值是 false 。

    Timer 还有 start()、stop()、restart() 三个方法可以调用,它们会影响 running 属性。


    十秒倒计时程序

    代码如下:

    import QtQuick 2.2
    import QtQuick.Controls 1.1
     
    Rectangle {
         320;
        height: 240;
        color: "gray";
        QtObject{
            id: attrs;
            property int counter;
            Component.onCompleted:{
                attrs.counter = 10;
            }
        }
        
        Text {
            id: countShow;
            anchors.centerIn: parent;
            color: "blue";
            font.pixelSize: 40;
        }
        
        Timer {
            id: countDown;
            interval: 1000;
            repeat: true;
            triggeredOnStart: true;
            onTriggered:{
                countShow.text = attrs.counter;
                attrs.counter -= 1;
                if(attrs.counter < 0)
                {
                    countDown.stop();
                    countShow.text = "Clap Now!";
                }
            }
        }
        
        Button {
            id: startButton;
            anchors.top: countShow.bottom;
            anchors.topMargin: 20;
            anchors.horizontalCenter: countShow.horizontalCenter;
            text: "Start";
            onClicked: {
                countDown.start();
            }
        }
    }
    

    我在界面上放了个 Text 对象,它下面放一按钮。 Rectangle 对象内定义了一个 Timer 对象,默认不启动。当用户点击 "Start" 按钮时启动定时器。我还设置了定时器的 triggeredOnStart 属性哦,周期是 1 秒。

    计数保存在 QtObject 对象中, id 是 attrs ,在附加信号处理程序 Component.onCompleted 中初始化 counter 属性的值为 10 。而在 Timer 对象的 onTriggered 信号处理器中递减 counter ,当 counter 为 0 时修改 Text 对象的文本为 "Clap Now!" 。


    来看下效果。下面是初始效果图:

    img


    下面是计时效果图:

    img


    下图是倒计时结束的效果图:


    img


    参考:

    《Qt Quick核心编程》第6章

    Qt Quick事件处理之鼠标、键盘、定时器


  • 相关阅读:
    HL 7.19 FFT多项式乘法
    HL 7.18 杂题整理 随笔
    BZOj 3208 食物 生成函数+广义二项式定理
    HL 7.14 整理杂题 随笔
    AC自动机 后缀数组 随笔
    Python 之time时间模块
    Python 之sys系统模块
    Uni-app 之猿产地项目
    Tkinter 之socket聊天室
    Python 之logging日志模块
  • 原文地址:https://www.cnblogs.com/linuxAndMcu/p/11935783.html
Copyright © 2020-2023  润新知