013-Qt 事件系统的小案例

auther: abinng date: 2026-05-09 09:36 createDate:2026-05-09 09:36

1. 多功能鼠标操作窗口

目的:了解一下鼠标事件

实现的效果:

  • 启动后,改变鼠标默认显示样式,松开和摁下左键的效果
  • 双击鼠标左键来使其全屏
  • 按着鼠标右键则使指针变为一个自定义的图片
  • 可以在界面上按着鼠标左键来拖动窗口
  • 使用滚轮可以放大或缩小编辑器中的内容
点击展开
1
2
3
4
5
6
7
8
9
#include <QApplication>
#include "MouseWidget.h"

int main(int argc, char *argv[]) {
QApplication a(argc, argv);
MouseWidget win;
win.show();
return QApplication::exec();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#ifndef EX17_MOUSE_MOUSEWIDGET_H
#define EX17_MOUSE_MOUSEWIDGET_H
#include <QWidget>
#include <QTextEdit>

class MouseWidget final : public QWidget {
Q_OBJECT
public:
explicit MouseWidget(QWidget* parent = nullptr);
~MouseWidget() override = default;
protected:
void mousePressEvent(QMouseEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override;
void mouseDoubleClickEvent(QMouseEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override;
void wheelEvent(QWheelEvent *event) override;
void closeEvent(QCloseEvent *event) override;
private:
QPointF offset;
QTextEdit* edit;
};

#endif //EX17_MOUSE_MOUSEWIDGET_H
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include <QCursor>
#include <QMouseEvent>
#include <QWheelEvent>
#include <QMessageBox>
#include "MouseWidget.h"

#include <QApplication>

MouseWidget::MouseWidget(QWidget *parent) : QWidget(parent) {
setGeometry(100, 100, 400, 400);
QCursor cursor;
cursor.setShape(Qt::OpenHandCursor);
setCursor(cursor);

edit = new QTextEdit(this);
edit->resize(200, 200);
edit->move(100, 100);
}

void MouseWidget::mousePressEvent(QMouseEvent *event) {
if (event->button() == Qt::LeftButton) {
QCursor cursor;
cursor.setShape(Qt::ClosedHandCursor);
QApplication::setOverrideCursor(cursor); // 暂时改变
offset = event->globalPosition() - pos();
} else if (event->button() == Qt::RightButton) {
QPixmap pixmap("./Doraemon.png");
qreal dpr = qApp->primaryScreen()->devicePixelRatio();
QSize logicalSize(64, 64);
QSize realSize = logicalSize * dpr;
pixmap = pixmap.scaled(realSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
pixmap.setDevicePixelRatio(dpr);
QCursor cursor(pixmap, logicalSize.width(), logicalSize.height());
QApplication::setOverrideCursor(cursor);
}
QWidget::mousePressEvent(event);
}

void MouseWidget::mouseReleaseEvent(QMouseEvent *event) {
Q_UNUSED(event);
QApplication::restoreOverrideCursor(); // 恢复鼠标指针
}

void MouseWidget::mouseDoubleClickEvent(QMouseEvent *event) {
if (event->button() == Qt::LeftButton) {
if (windowState() != Qt::WindowFullScreen)
setWindowState(Qt::WindowFullScreen);
else
setWindowState(Qt::WindowNoState);
}
QWidget::mouseDoubleClickEvent(event);
}

void MouseWidget::mouseMoveEvent(QMouseEvent *event) {
if (event->buttons() & Qt::LeftButton) {
QPointF temp = event->globalPosition() - offset;

move(temp.x(), temp.y());
}
}

void MouseWidget::wheelEvent(QWheelEvent *event) {
if (event->angleDelta().y() > 0) {
edit->zoomIn();
} else {
edit->zoomOut();
}
}

void MouseWidget::closeEvent(QCloseEvent *event) {
QString title = "鼠标事件框";
QString info = "确定退出吗?";
QMessageBox::StandardButton result = QMessageBox::question(this, title, info, QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
if (result == QMessageBox::Yes) {
event->accept();
} else {
event->ignore();
}
}

2. 键盘支持和定时器事件

目的:了解一下键盘事件和定时器事件

实现的效果:

  • 支持 W, S, A, D 键或上下左右实现按键控件的移动
  • 支持Ctrl + Q退出当前主窗口
  • 按键上面显示时间,格式为 “mm:ss”
点击展开
1
2
3
4
5
6
7
8
9
#include <QApplication>
#include "keyWidget.h"

int main(int argc, char *argv[]) {
QApplication a(argc, argv);
keyWidget key;
key.show();
return QApplication::exec();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#ifndef EX18_KEYEVENT_KEYWIDGET_H
#define EX18_KEYEVENT_KEYWIDGET_H
#include <QWidget>
#include <QPushButton>

class keyWidget : public QWidget {
public:
explicit keyWidget(QWidget* parent = nullptr);
~keyWidget() override = default;
protected:
void keyPressEvent(QKeyEvent *event) override;
void timerEvent(QTimerEvent *event) override;
private:
QPushButton* btn_move;
int id1;
int id2;
};


#endif //EX18_KEYEVENT_KEYWIDGET_H
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include "keyWidget.h"
#include <QKeyEvent>
#include <QTimerEvent>
#include <QTimer>
#include <QTime>

keyWidget::keyWidget(QWidget *parent) : QWidget(parent) {
setGeometry(100, 100, 400, 400);
setFocusPolicy(Qt::StrongFocus);
setFocus();
btn_move = new QPushButton(this);
btn_move->resize(80, 80);
btn_move->setText("Move Button");

id1 = startTimer(1000);
id2 = startTimer(2500);
QTimer *timer = new QTimer(this);
timer->start(1000);

connect(timer, &QTimer::timeout, [=]() {
QTime abc = QTime::currentTime();
btn_move->setText(abc.toString("mm:ss"));
});
}

void keyWidget::keyPressEvent(QKeyEvent *event) {
QPoint pt = btn_move->pos();
if (event->key() == Qt::Key_A || event->key() == Qt::Key_Left) {
btn_move->move(pt.x() - 20, pt.y());
} else if (event->key() == Qt::Key_S || event->key() == Qt::Key_Down) {
btn_move->move(pt.x(), pt.y() + 20);
} else if (event->key() == Qt::Key_D || event->key() == Qt::Key_Right) {
btn_move->move(pt.x() + 20, pt.y());
} else if (event->key() == Qt::Key_W || event->key() == Qt::Key_Up) {
btn_move->move(pt.x(), pt.y() - 20);
} else if (event->modifiers() == Qt::ControlModifier && event->key() == Qt::Key_Q) {
emit close();
}
event->accept();
}

void keyWidget::timerEvent(QTimerEvent *event) {
static int id1_cnt;
if (event->timerId() == id1) {
id1_cnt++;
qDebug() << "timer1";
if (id1_cnt == 5) {
killTimer(id1);
}
} else if (event->timerId() == id2) {
qDebug() << "timer2";
} else {
qDebug() << "other timer";
}
}