zoukankan      html  css  js  c++  java
  • Qt事件循环

    Qt程序执行QApplication::exec()函数后,将进入事件循环来监听应用程序的事件,Qt中所有的事件类都继承于QEvent。

    事件发生时,Qt创建一个事件对象,传递给QObject的event()函数,event()函数并不直接处理事件,而是对这些事件按照它们不同的类型分发给不同的事件处理函数。

    event()函数主要用于事件的分发,如果要在事件分发之前做一些操作,就需要重写event()函数。

    鼠标事件:

    #include <QMouseEvent>

    1 void mousePressEvent(QMouseEvent *event);               //单击
    2 void mouseReleaseEvent(QMouseEvent *event);             //释放
    3 void mouseDoubleClickEvent(QMouseEvent *event);         //双击
    4 void mouseMoveEvent(QMouseEvent *event);                //移动
    5 void wheelEvent(QWheelEvent *event);                    //滚轮
     1 void QtEventTest::mousePressEvent(QMouseEvent *event)
     2 {
     3     if (event->button() == Qt::LeftButton)
     4     {
     5 
     6     }
     7     else if (event->button() == Qt::RightButton)
     8     {
     9 
    10     }
    11 }
    12 
    13 void QtEventTest::mouseReleaseEvent(QMouseEvent *event)
    14 {
    15 
    16 }
    17 
    18 void QtEventTest::mouseDoubleClickEvent(QMouseEvent *event)
    19 {
    20     if (event->button() == Qt::LeftButton)
    21     {
    22     }
    23     else if (event->button() == Qt::RightButton)
    24     {
    25     }
    26 }
    27 
    28 void QtEventTest::mouseMoveEvent(QMouseEvent *event)        //默认情况下,此触发事件需要点击一下,才能触发。可设置为自动触发:setMouseTracking(true);
    29 {
    30     if (event->buttons() & Qt::LeftButton)  //buttons() 位与 左击
    31     {
    32     }
    33 }
    34 
    35 void QtEventTest::wheelEvent(QWheelEvent *event)
    36 {
    37     if (event->delta() > 0)
    38     {
    39         //远离使用者方向滚动
    40     }
    41     else
    42     {
    43         //靠近使用者方向滚动
    44     }
    45 }

    Qt中buttons()和button()的区别,官方解析如下:

    Qt::MouseButton QMouseEvent::button() const

    返回产生事件的按钮

    Qt::MouseButton QMouseEvent::buttons() const

    返回产生事件的按钮状态,函数返回当前按下的所有按钮,按钮状态可以是Qt::LeftButton,Qt::RightButton,Qt::MidButton或运算组合

    假设鼠标左键已经按下,
    如果移动鼠标,会发生的move事件,button返回Qt::NoButton,buttons返回LeftButton。
    再按下了右键,会发生press事件,button返回RightButton,buttons返回LeftButton | RightButton
    再移动鼠标,会发生move事件,button返回Qt::NoButton,buttons返回LeftButton | RightButton
    再松开左键,会发生Release事件,button返回LeftButton,buttons返回RightButton
    也就是说,button返回“那个按钮发生了此事件”,buttons返回"发生事件时哪些按钮还处于按下状态"

    键盘事件:
    #include <QKeyEvent>

    1 void keyPressEvent(QKeyEvent *event);                   //按下
    2 void keyReleaseEvent(QKeyEvent *event);                 //释放

    从网上查资料发现,Qt的按键消息响应keyPressEvent()表现为按住一个键时,会先响应一次,停顿一会,然后开始不断响应。

    而且Qt的键盘函数有一个问题,它不是“按下按键才触发keyPressEvent(), 弹起按键才触发keyReleaseEvent()",而是”输出按键消息前触发keyPressEvent(),输出后触发keyReleaseEvent()“,表现为按住一个键时,不断地press、release、press、release、press、release......

    Qt的QKeyEvent类中提供isAutoRepeat()判断,即按住按键时触发的那些键盘事件isAutoRepeat类型,可以据此排除中间触发的那些press和release

    综上所述,Qt的键盘事件整体表现为,按住一个键时:
    1、第一次触发keyPressEvent(), isAutoRepeat()返回false

    2、没有触发keyReleaseEvent(),停顿一会

    3、再一次触发keyPressEvent(),isAutoRepeat()返回true

    4、触发keyReleaseEvent()

    5、若没松开按键,isAutoRepeat()返回true,返回第3步;若松开按键,isAutoRepeat()返回false

     1 void QtEventTest::keyPressEvent(QKeyEvent *event)
     2 {
     3     if (event->key() == Qt::Key_Up)
     4     {
     5         //避免自动重复,按键重复时return;
     6         if (event->isAutoRepeat())
     7         {
     8             return;
     9         }
    10 
    11                 ...
    12         keyUp = true;  //标记向上方向键已经按下
    13     }
    14     else if (event->key() == Qt::Key_Left)
    15     {
    16         if (event->isAutoRepeat())
    17         {
    18             return;
    19         }
    20 
    21                 ...
    22         keyLeft = true;  
    23     }
    24 }
    25 
    26 void QtEventTest::keyReleaseEvent(QKeyEvent *event)
    27 {
    28     if (event->key() == Qt::Key_Up)
    29     {
    30         if (event->isAutoRepeat())
    31         {
    32             return;
    33         }
    34                 
    35                 ...
    36     }
    37     else if (event->key() == Qt::Key_Left)
    38     {
    39         if (event->isAutoRepeat())
    40         {
    41             return;
    42         }
    43 
    44                 ...
    45     }
    46 }
  • 相关阅读:
    Unity3D笔记 英保通三 脚本编写 、物体间通信
    Unity3D笔记 英保通二
    Unity3D 面试ABC
    Unity3D 记第一次面试
    Unity3D笔记 英保通一
    (转)关于如何学好游戏3D引擎编程的一些经验
    Java_异常
    Java_多态
    Java_继承(下)
    Java_继承(上)
  • 原文地址:https://www.cnblogs.com/Jace-Lee/p/5869170.html
Copyright © 2011-2022 走看看