目录
- 1.事件介绍
- 2.事件的处理
- 3.鼠标事件
- 4.按键事件
- 5.moveEvent
- 6.resizeEvent
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) {} }
- 在Qt中,键盘事件可以与修改键⼀起使⽤,以实现⼀些复杂的交互操作
5.moveEvent
moveEvent
:窗口移动时触发的事件- 示例:
void Widget::moveEvent(QMoveEvent *event) { qDebug() << event->pos(); }
6.resizeEvent
resizeEvent
:窗口大小改变时触发的事件- 示例:
void Widget::resizeEvent(QResizeEvent *event) { qDebug() << event->size(); }