[Qt][Qt 事件][上]详细讲解


1.事件介绍

  • 事件是应⽤程序内部或者外部产⽣的事情或者动作的统称

  • 在Qt中使⽤⼀个对象来表⽰⼀个事件,所有的Qt事件均继承于抽象类QEvent

  • 事件是由系统或者Qt平台本⾝在不同的时刻发出的

    • 当⽤⼾按下⿏标、敲下键盘,或者是窗⼝需要重新绘制的时候,都会发出⼀个相应的事件
      • ⼀些事件是在⽤⼾操作时发出,如键盘事件、⿏标事件等
      • 另⼀些事件则是由系统本⾝⾃动发出,如定时器事件
  • 常⻅的Qt事件如下
    请添加图片描述

  • 常见事件描述

    事件名称描述
    ⿏标事件⿏标左键、⿏标右键、⿏标滚轮,⿏标的移动,⿏标按键的按下和松开
    键盘事件按键类型、按键按下、按键松开
    定时器事件定时时间到达
    进⼊离开事件⿏标的进⼊和离开
    滚轮事件⿏标滚轮滚动
    绘屏事件重绘屏幕的某些部分
    显⽰隐藏事件窗⼝的显⽰和隐藏
    移动事件窗⼝位置的变化
    窗⼝事件是否为当前窗⼝
    ⼤⼩改变事件窗⼝⼤⼩改变
    焦点事件键盘焦点移动
    拖拽事件⽤⿏标进⾏拖拽
  • 事件和信号槽有什么区别?

    • 事件本身是OS提供的机制,Qt同样把OS事件机制进行了封装,拿到了Qt中
    • 但是由于事件对应的代码编写起来不是很方便,Qt又对事件机制进行了更进一步的封装,就得到了信号槽
    • 综上:信号槽是对事件的进一步封装,事件是信号槽的底层机制
  • 何时用信号槽,何时用事件呢?

    • 实际Qt开发过程中,绝大部分和用户之间进行的交互都是通过"信号槽"来完成的
    • 有些特殊情况下,信号槽不一定能搞得定(用户的某个行为动作,Qt没有提供对应的信号),此时就需要通过重写事件处理函数的形式,来手动处理事件的响应逻辑
  • 信号槽和事件使用上的区别?

    • 信号槽通过connect()来关联代码和"事件"
    • 事件通过当前类重写某个事件处理函数 --> 多态机制
  • 事件存在的意义?

    • 开放事件机制给程序员,就可以根据实际需要,进行更深度的定制化DIY操作

2.事件的处理

  • 事件处理⼀般常⽤的⽅法为:重写相关的Event函数
  • 在Qt中,⼏乎所有的Event函数都是虚函数,所以可以重新实现
    • 如:在实现⿏标的进⼊和离开事件时,直接重新实现enterEvent()leaveEvent()即可

      请添加图片描述


3.鼠标事件

  • 在Qt中,⿏标事件是⽤QMouseEvent类来实现的
  • 当在窗⼝中按下⿏标或者移动⿏标时,都会产⽣⿏标事件
  • 鼠标左右键表示如下
    • Qt::LeftButton:⿏标左键
    • Qt::RightButton:⿏标右键
    • Qt::MidButton:⿏标滚轮
  • 鼠标点击事件:通过虚函数mousePressEvent()来捕获
    • 说明
      • 按下左键、右键、滚轮都能触发,有的鼠标带的前进后退侧键也能触发
      • 但是有的鼠标还提供了更多的按键,就不一定支持了
    • 示例
      void Label::mousePressEvent(QMouseEvent *event)
      {
      	if (event->button() == Qt::LeftButton) {} 
      	else if (event->button() == Qt::RightButton) {}
      	
      	// 当前 event 对象就包含了鼠标点击位置的坐标
      	// x() 和 y() 是以当前组件的左上角为原点,获取的坐标
      	qDebug() << event->x() << ", " << event->y();
      	
      	// globalX 和 globalY 是以屏幕左上角为原点, 获取的坐标.
      	qDebug() << event->globalX() << ", " << event->globalY();
      }
      
  • 鼠标释放事件:通过虚函数mouseReleaseEvent()来捕获
  • 鼠标双击事件:通过虚函数mouseDoubleClickEvent()来捕获
    • 说明:双击事件默认是会判定第二次单击为双击,所以会正常触发第一次单击事件
      • 有的程序,可能单机有一些逻辑,双击也有一些逻辑,如果编写程序时不注意,可能双击操作也会触发单击的逻辑,此时就会存在潜在的bug
  • 鼠标移动事件:通过虚函数mouseMoveEvent()来捕获,同时为了实时捕获⿏标位置信息,需要通过函数setMouseTracking()追踪⿏标的位置
    • 说明setMouseTracking()默认是false,需要设置为true,才能实时捕获⿏标位置信息,否则只有当⿏标按下时才能捕获其位置信息
      • 因为鼠标移动不同于鼠标按下,随便移动一下鼠标,就会产生出大量的鼠标移动事件
      • 当进行捕获事件的时候,尤其是在进行复杂逻辑的时候,程序负担很重,很容易产生卡顿之类的情况
      • Qt为了保证程序的流畅性,默认情况不会对鼠标移动进行追踪,所以鼠标移动的时候不会调用mouseMoveEvent()
    • 示例
      // 构造函数中
      {
          // 把这个选项设置为 true, 才能够追踪鼠标的移动位置.
          this->setMouseTracking(true);
      }
      
      void Widget::mouseMoveEvent(QMouseEvent* event)
      {
          qDebug() << event->x() << event->y();
      }
      
  • 滚轮事件:通过QWheelEvent类来实现的,滚轮滑动的距离可以通过delta()获取
    • 函数原型int QGraphicsSceneWheelEvent::delta() const
    • 说明:其中返回值代表滚轮滑动的距离
      • 正数表⽰滚轮相对于⽤⼾向前滑动
      • 负数表⽰滚轮相对于⽤⼾向后滑动
    • 示例
      void Widget::wheelEvent(QWheelEvent *event)
      {
          qDebug() << event->delta();
      }
      

4.按键事件

  • 怎样获取到键盘按键?
    • 方式一QShortCut:通过信号槽封装的机制,获取键盘按键
    • 方式二:站在更底层的角度,通过事件获取到当前用户键盘按下的情况
  • Qt中的按键事件是通过QKeyEvent类来实现的
  • 当键盘上的按键被按下或者被释放时,键盘事件便会触发
  • 单个按键:重写keyPressEvent()虚函数
    • 示例
      void Widget::keyPressEvent(QKeyEvent *event)
      {
          if (event->key() == Qt::Key_A){}
      }
      
  • 组合按键:同样重写keyPressEvent()虚函数,但是可以搭配Qt::KeyboardModifier中定义的在处理键盘事件时对应的修改键
    • 在Qt中,键盘事件可以与修改键⼀起使⽤,以实现⼀些复杂的交互操作
      • Qt::NoModifier:⽆修改键
      • Qt::ShiftModifier:Shift 键
      • Qt::ControlModifier:Ctrl 键
      • Qt::AltModifier:Alt 键
      • Qt::MetaModifier:Meta键
        • 在Windows上指Windows键,在MacOS上指Command键
      • Qt::KeypadModifier:使⽤键盘上的数字键盘进⾏输⼊时,NumLock键处于打开状态
      • Qt::GroupSwitchModifier ⽤于在输⼊法组之间切换
    • 示例
      void Widget::keyPressEvent(QKeyEvent *event)
      {
          if (event->key() == Qt::Key_A && 
      	    event->modifiers() == Qt::ControlModifier) 
          {}
      }
      

5.moveEvent

  • moveEvent:窗口移动时触发的事件
  • 示例
    void Widget::moveEvent(QMoveEvent *event)
    {
        qDebug() << event->pos();
    }
    

6.resizeEvent

  • resizeEvent:窗口大小改变时触发的事件
  • 示例
    void Widget::resizeEvent(QResizeEvent *event)
    {
        qDebug() << event->size();
    }
    

评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DieSnowK

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值