一.事件流程
1.事件生成:
用户输入:例如,用户点击鼠标或按下键盘键。
系统事件:例如,窗口被移动或调整大小。
自定义事件:应用程序内部生成的事件,如定时器超时。
2.事件传递:
事件被封装成 QEvent 对象,并放入事件队列中。
事件队列通常由 QApplication 或 QCoreApplication 管理。
3.事件分发:
QApplication 或 QCoreApplication 的 exec() 方法启动主事件循环。
事件循环不断从事件队列中取出事件,并调用 QApplication::notify 方法。
QApplication::notify 方法将事件分发给目标对象。
4.事件处理:
目标对象的 event 方法被调用,处理事件。
如果 event 方法返回 true,表示事件已被处理;如果返回 false,表示事件未被处理,可能需要进一步处理。
特定的事件处理方法:例如,mousePressEvent、keyPressEvent 等。
5.事件过滤器:
对象可以安装事件过滤器,通过 installEventFilter 方法。
事件过滤器的 eventFilter 方法会在目标对象的 event 方法之前被调用。
事件过滤器可以拦截并处理事件,或者让事件继续传递给目标对象。
二.实际操作
1.统一流程
-
main.cpp
- 创建
QApplication
对象,初始化应用程序。 - 创建
MyWidget
对象并显示。 - 进入主事件循环
app.exec()
。
- 创建
-
mywidget.h
- 定义
MyWidget
类,继承自QWidget
。 - 声明
mousePressEvent
和keyPressEvent
方法,用于处理鼠标点击和键盘按键事件。
- 定义
-
mywidget.cpp
- 实现
MyWidget
构造函数,设置窗口大小。 - 实现
mousePressEvent
方法,获取鼠标点击的位置和按钮,并输出信息。 - 实现
keyPressEvent
方法,获取按下的键,并输出信息。
- 实现
2.例子流程:
1.(widget.h)文件
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QEvent> // 事件
#include <QMouseEvent> // 鼠标事件
#include <QKeyEvent> // 键盘事件
#include <QWheelEvent> // 滚轮事件
#include <QTimerEvent> // 定时器事件
#include <QPaintEvent> // 绘图事件
class Widget : public QWidget
{
Q_OBJECT
// 重写各种事件处理函数
// 事件处理的总的入口函数
bool event(QEvent *event);
// 一.鼠标事件
// 1.鼠标点击事件
void mousePressEvent(QMouseEvent *event); //按下
void mouseReleaseEvent(QMouseEvent *event); //松开
void mouseMoveEvent(QMouseEvent *event); //移动
void mouseDoubleClickEvent(QMouseEvent *event); //双击
// 2.滚轮事件
void wheelEvent(QWheelEvent *event);
// 二.键盘事件
void keyPressEvent(QKeyEvent *event);
void keyReleaseEvent(QKeyEvent *event);
// 三.定时器事件
void timerEvent(QTimerEvent *event);
// 四.绘图事件
void paintEvent(QPaintEvent *event);
// 五.离开 进入事件
void leaveEvent(QEvent *event);
void enterEvent(QEvent *event);
public:
Widget(QWidget *parent = 0);
~Widget();
};
#endif // WIDGET_H
2.(main.cpp)文件
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
3.(widget.cpp)文件
#include "widget.h"
#include <QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
setWindowTitle("事件处理");
// 启动自带定时器 3000ms
startTimer(3000);
}
Widget::~Widget()
{
}
// 事件处理的总的入口函数
// bool 表示该事件是否已经处理完毕
// true 表示已经处理完毕, 不会再交给其他的窗口控件去处理
// false 表示没有处理完毕, 可以继续处理
bool Widget::event(QEvent *event){
//
if (event->type() == QEvent::MouseButtonPress)
{
qDebug() << "event总入口 鼠标点击事件";
QMouseEvent *tmp = static_cast<QMouseEvent*>(event);
qDebug() << ("event(), pos = ") << tmp->pos();
}
else if (event->type() == QEvent::KeyPress)
{
qDebug() << "event总入口 键盘点击事件";
}
// 继续调用基类的事件处理总入口函数, 维持原有的行为
return QWidget::event(event);
}
// 一.鼠标事件
// 1.鼠标点击事件
//按下 //松开 //移动 //双击
void Widget::mousePressEvent(QMouseEvent *event){
// 按下的什么键
if (event->button() == Qt::LeftButton)
{
qDebug() << "鼠标按下 左键";
}
else if (event->button() == Qt::RightButton)
{
qDebug() << "鼠标按下 右键";
}
else if (event->button() == Qt::MidButton)
{
qDebug() << "鼠标按下 中键";
}
// 按下的位置
// 在应用程序的位置
qDebug() << event->pos();
qDebug() << event->x() << "|" << event->y();
// 在整个屏幕的位置
qDebug() << event->globalPos();
}
void Widget::mouseReleaseEvent(QMouseEvent *event){
// 按下的什么键
if (event->button() == Qt::LeftButton)
{
qDebug() << "鼠标松开 左键";
}
else if (event->button() == Qt::RightButton)
{
qDebug() << "鼠标松开 右键";
}
else if (event->button() == Qt::MidButton)
{
qDebug() << "鼠标松开 中键";
}
// 按下的位置
// 在应用程序的位置
qDebug() << event->pos();
qDebug() << event->x() << "|" << event->y();
// 在整个屏幕的位置
qDebug() << event->globalPos();
}
void Widget::mouseMoveEvent(QMouseEvent *event){
qDebug() << "鼠标移动";
qDebug() << event->pos();
}
void Widget::mouseDoubleClickEvent(QMouseEvent *event){
qDebug() << "鼠标双击事件";
qDebug() << event->pos();
}
// 2.鼠标滚轮事件
void Widget::wheelEvent(QWheelEvent *event){
qDebug() << "滚轮";
qDebug() << event->delta();
}
// 二.键盘事件
void Widget::keyPressEvent(QKeyEvent *event){
qDebug() << "键盘按下键事件";
qDebug() << "key = " << QString(QChar(event->key()));
}
void Widget::keyReleaseEvent(QKeyEvent *event){
qDebug() << "键盘松开键事件";
qDebug() << "key = " << QString(QChar(event->key()));
}
// 三.定时器事件
// QObject 自带一个定时器
void Widget::timerEvent(QTimerEvent *event){
qDebug() << "超时事件";
}
// 四.绘图事件
void Widget::paintEvent(QPaintEvent *event){
static int c = 1;
qDebug() << "绘图事件 " << c++;
}
// 五.离开 进入事件
void Widget::leaveEvent(QEvent *event){
qDebug() << "离开事件";
}
void Widget::enterEvent(QEvent *event){
qDebug() << "进入事件";
}