QT-事件机制学习笔记

  • 一、事件
  • 二、事件处理函数
  • 三、事件分发机制
  • 四、事件过滤器
  • 五、定时器事件
  • 六、绘图
  • 七、手动触发绘图事件
  • 八、绘图设备

一、事件

 事件(event)是由系统或者Qt应用程序本身在不同的时刻发出的,当用户按下鼠标、敲下键盘,或者是窗口需要重新绘制的时候,都会发出一个相应的事件

二、事件处理函数

  • keyPressEvent(): 键盘按键按下事件
  • keyReleaseEvent(): 键盘按键松开事件
  • mouseDoubleClickEvent():鼠标双击事件

重写鼠标按下事件:mousePressEvent
mylabel.h

#ifndef MYLABEL_H
#define MYLABEL_H#include <QWidget>
#include<QLabel>// 继承QLabel
class MyLabel : public QLabel
{Q_OBJECT
public:explicit MyLabel(QWidget *parent = nullptr);signals:public slots:protected:// 重写鼠标按键处理函数  参数是鼠标点击事件void mousePressEvent(QMouseEvent *ev);
};#endif // MYLABEL_H

mylabel.cpp

#include "mylabel.h"
#include<QMouseEvent>MyLabel::MyLabel(QWidget *parent): QLabel{parent}
{}void MyLabel::mousePressEvent(QMouseEvent *ev)
{// 输出鼠标事件的一些信息// 获取坐标int x = ev->x();int y = ev->y();QString str = QString("[%1,%2]").arg(x).arg(y);// 鼠标按下  实时输出坐标信息this->setText(str);
}

重写鼠标移动的处理函数:mouseMoveEvent

mylabel.h

#ifndef MYLABEL_H
#define MYLABEL_H#include <QWidget>
#include<QLabel>// 继承QLabel
class MyLabel : public QLabel
{Q_OBJECT
public:explicit MyLabel(QWidget *parent = nullptr);signals:public slots:protected:// 重写鼠标按键处理函数  参数是鼠标点击事件void mousePressEvent(QMouseEvent *ev);// 重写鼠标移动的处理函数void mouseMoveEvent(QMouseEvent *ev);
};#endif // MYLABEL_H

mylabel.cpp

#include "mylabel.h"
#include<QMouseEvent>MyLabel::MyLabel(QWidget *parent): QLabel{parent}
{}void MyLabel::mousePressEvent(QMouseEvent *ev)
{// 输出鼠标事件的一些信息// 获取坐标int x = ev->x();int y = ev->y();// 获取鼠标按键Qt::MouseButton btn = ev->button();QString strbutton ="";if(btn == Qt::LeftButton){strbutton = "LeftButton";}if(btn == Qt::RightButton){strbutton = "RightButton";}if(btn == Qt::MidButton){strbutton = "MidButton";}QString str = QString("<h1>press[%1,%2][%3]</h1>").arg(x).arg(y).arg(strbutton);// 鼠标按下  实时输出坐标信息this->setText(str);
}void MyLabel::mouseMoveEvent(QMouseEvent *ev)
{// 输出鼠标事件的一些信息// 获取坐标int x = ev->x();int y = ev->y();// 获取鼠标按键Qt::MouseButton btn = ev->button();QString strbutton ="";if(btn == Qt::LeftButton){strbutton = "LeftButton";}if(btn == Qt::RightButton){strbutton = "RightButton";}if(btn == Qt::MidButton){strbutton = "MidButton";}QString str = QString("<h1>move[%1,%2][%3]</h1>").arg(x).arg(y).arg(strbutton);// 鼠标按下  实时输出坐标信息this->setText(str);
}

三、事件分发机制

当某个事件(鼠标或者键盘)发生的时候,窗口就会收到这个事件,并且调用相应的事件处理函数,事件处理函数的命名都是以event结尾

事件先回到达窗口的event函数,event函数返回值:true表示该事件得到处理,如果是false,没被处理,时间会继续传递到父窗口,通过判断QEvent参数的类型得到事件类型之后,调用相应的事件处理函数

MyLabel.cpp

bool MyLabel::event(QEvent *e)
{// 返回值:true表示该事件得到处理 如果是false 没被处理 事件会继续传递到父窗口// QEvent就是所有Event类的父类// 判断event的类型if(e->type() == QEvent::MouseMove){this->mouseMoveEvent(static_cast<QMouseEvent *>(e));// 转换一下数据类型}return QLabel::event(e);}

MyLabel.h

#ifndef MYLABEL_H
#define MYLABEL_H#include <QWidget>
#include<QLabel>// 继承QLabel
class MyLabel : public QLabel
{Q_OBJECT
public:explicit MyLabel(QWidget *parent = nullptr);signals:public slots:protected:// 重写鼠标按键处理函数  参数是鼠标点击事件void mousePressEvent(QMouseEvent *ev);// 重写鼠标移动的处理函数void mouseMoveEvent(QMouseEvent *ev);// 重写event分发函数bool event(QEvent *e);
};#endif // MYLABEL_H

四、事件过滤器

MyLabel.cpp

#include "mylabel.h"
#include<QMouseEvent>MyLabel::MyLabel(QWidget *parent): QLabel{parent}
{this->setMouseTracking(true);// 事件过滤器的使用// 窗口调用installEventFilter 来安装一个事件过滤器// 参数是一个事件过滤器对象QObject,该对象的类要重写eventFilter的函数// 事件过滤的时候 事件会先到达事件过滤器的eventFilter函数this->installEventFilter(this);
}void MyLabel::mousePressEvent(QMouseEvent *ev)
{// 输出鼠标事件的一些信息// 获取坐标int x = ev->x();int y = ev->y();// 获取鼠标按键Qt::MouseButton btn = ev->button();QString strbutton ="";if(btn == Qt::LeftButton){strbutton = "LeftButton";}if(btn == Qt::RightButton){strbutton = "RightButton";}if(btn == Qt::MidButton){strbutton = "MidButton";}QString str = QString("<h1>press[%1,%2][%3]</h1>").arg(x).arg(y).arg(strbutton);// 鼠标按下  实时输出坐标信息this->setText(str);
}void MyLabel::mouseMoveEvent(QMouseEvent *ev)
{// 输出鼠标事件的一些信息// 获取坐标int x = ev->x();int y = ev->y();// 获取鼠标按键Qt::MouseButton btn = ev->button();QString strbutton ="";if(btn == Qt::LeftButton){strbutton = "LeftButton";}if(btn == Qt::RightButton){strbutton = "RightButton";}if(btn == Qt::MidButton){strbutton = "MidButton";}QString str = QString("<h1>move[%1,%2][%3]</h1>").arg(x).arg(y).arg(strbutton);// 鼠标按下  实时输出坐标信息this->setText(str);
}bool MyLabel::event(QEvent *e)
{// 返回值:true表示该事件得到处理 如果是false 没被处理 事件会继续传递到父窗口// QEvent就是所有Event类的父类// 判断event的类型if(e->type() == QEvent::MouseMove){this->mouseMoveEvent(static_cast<QMouseEvent *>(e));// 转换一下数据类型}return QLabel::event(e);}bool MyLabel::eventFilter(QObject *watched, QEvent *event)
{// 拦截鼠标移动事件if(event->type() == QEvent::MouseMove){return true;}
}

MyLabel.h

#ifndef MYLABEL_H
#define MYLABEL_H#include <QWidget>
#include<QLabel>// 继承QLabel
class MyLabel : public QLabel
{Q_OBJECT
public:explicit MyLabel(QWidget *parent = nullptr);signals:public slots:protected:// 重写鼠标按键处理函数  参数是鼠标点击事件void mousePressEvent(QMouseEvent *ev);// 重写鼠标移动的处理函数void mouseMoveEvent(QMouseEvent *ev);// 重写event分发函数bool event(QEvent *e);// 重写eventFilterbool eventFilter(QObject *watched,QEvent *event);
};#endif // MYLABEL_H

五、定时器事件

  • 通过startTimer来启动一个定时器,参数是毫秒,每隔相应的事件就会触发一个定时器事件,返回值就是定时器的Id
  • 通过killTimer来杀死一个定时器,参数就是定时器的Id
  • timerEvent定时器事件处理函数中通过event参数获取当前事件是哪一个定时器发出的,event->timerId()

widget.h

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTprotected:// 定时器事件的处理void timerEvent(QTimerEvent *event);public:Widget(QWidget *parent = nullptr);~Widget();private:Ui::Widget *ui;
};
#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include<QDebug>void Widget::timerEvent(QTimerEvent *event)
{qDebug()<<"闹钟";
}Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//创建定时器startTimer(1000);}Widget::~Widget()
{delete ui;
}

六、绘图

绘图事件:窗口需要重新显示的时候,就会收到一个绘图事件,paintEvent收到绘图事件之后,窗口就要讲自己画出来

画画的人:QPainter
画笔:QPen
画布:QPaintDevice

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include<QPainter>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);
}Widget::~Widget()
{delete ui;
}void Widget::paintEvent(QPaintEvent *event)
{// 在这里画画  设置一个画布QPainter painter(this);// 创建一支画笔QPen pen;pen.setWidth(3);pen.setColor(QColor(255,0,0));// 设置颜色// 画刷QBrush brush;brush.setColor(Qt::cyan);// 画刷颜色// 画家设置画刷painter.setBrush(brush);// 画家设置画笔painter.setPen(pen);pen.setStyle(Qt::DashLine);// 设置画笔风格// 画一条线painter.drawLine(0,0,100,100);// 画矩形painter.drawRect(20,20,50,50);// 画圆形  使用椭圆painter.drawEllipse(QPoint(100,100),50,50);// 文字painter.drawText(200,100,"好好学习 天天向上");
}

widget.h

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private:Ui::Widget *ui;protected:// 设置绘图事件void paintEvent(QPaintEvent *event);};
#endif // WIDGET_H
  • QPainter(参数是绘图设备,this表示在窗口上)
  • drawLine 划线 两点一线 参数就是两个点的坐标
  • drawRect 矩形 参数是左上角点 宽和高 另一种就是圆心 + rx + ry
  • 设置画家的画笔 setPen(QPen) 画笔可以设置颜色风格
  • 设置画家的画刷 setBrush(QBrush) 填充封闭的图形 也可以设置颜色

七、手动触发绘图事件

使用两个函数:

  • repaint:会马上触发绘图事件
  • update:update做了一些优化
  • 不要在paintEvent处理函数中再触发绘图事件,会导致无限循环

widget.h

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private:Ui::Widget *ui;public:int mPox;protected:// 设置绘图事件void paintEvent(QPaintEvent *event);private slots:void on_pushButton_clicked();
};
#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include<QPainter>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);mPox = 0;}Widget::~Widget()
{delete ui;
}void Widget::paintEvent(QPaintEvent *event)
{// painter绘制已经存在的图片QPainter painter(this);QPixmap pixmap(":/Talyor/T001M001000qrPik2w6lDr_99.jpg");painter.drawPixmap(mPox,0,pixmap);// 绘制图像
}void Widget::on_pushButton_clicked()
{// 每次点击按钮 图片向右移动 10pxmPox += 10;// 手动触发绘图事件// repaint// updatethis->update();
}

八、绘图设备

  • QPixmap专门为图像在屏幕上的显示做了优化
  • QBitmap是QPixmax的一个子类,他的色深限定为1,可以使用QPixmap的isQBitmapx()函数来确定这个QPixmap是不是一个QBitmap.
  • QImage专门为图像的像素级访问做了优化
  • QPicture则可以记录何重现QPainter的逐条命令
  • 图片可以通过save和load命令进行加载以及保存
#include "widget.h"
#include "ui_widget.h"
#include<QPainter>
#include<QPixmap>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QPixmap pix(300,300);// 设置300 x 300绘图区域pix.fill(Qt::white);// 将画布背景填充为白色QPainter painter(&pix);// 设置画笔颜色painter.setPen(QColor(255,0,0));painter.drawEllipse(QPoint(150,150),100,100);// 绘制椭圆pix.save("D:\\pictures\\hh.png");// 保存图片
}Widget::~Widget()
{delete ui;
}

QT-事件机制学习笔记相关推荐

  1. Qt 快速入门学习笔记

    Qt 快速入门学习笔记 环境安装 环境配置以及安装 安装包下载地址 1.windows安装 msvc编译器模块需要安装Windows软件开发工具包. MinGW是Windows平台使用GNU工具导入库 ...

  2. QT 5.9学习笔记

    QT 5.9学习笔记 写在前面 S1:初识QT:QT简介 S2:QT在Windows和Linux平台下的安装 Qt调出模态与非模态对话框 写在前面 本文章为我在学习QT5.9时的记录文章,里面会涉及所 ...

  3. Qt 5.12学习笔记--QML性能策略

    Qt 5.12学习笔记--QML性能策略 1 简介 2 时间因素 2 性能分析 3 JavaScript 部分 4 绑定 5 类型转换 6 解析属性 6 属性绑定 7 序列提示(Sequence ti ...

  4. Windows事件等待学习笔记(二)—— 线程等待与唤醒

    Windows事件等待学习笔记(二)-- 线程等待与唤醒 要点回顾 等待与唤醒机制 可等待对象 可等待对象的差异 线程与等待对象 一个线程等待一个对象 实验 第一步:编译并运行以下代码 第二步:在Wi ...

  5. Windows事件等待学习笔记(一)—— 临界区自旋锁

    Windows事件等待学习笔记(一)-- 临界区&自旋锁 基础知识 演示代码 案例一 案例二 LOCK 单行代码原子操作 多行代码原子操作 临界区 演示代码 手动实现 自旋锁 分析 KeAcq ...

  6. 【vn.py学习笔记(三)】vn.py事件引擎 学习笔记

    [vn.py学习笔记(三)]vn.py事件引擎 学习笔记 1 时间驱动 2 事件驱动 3 事件引擎工作流程 4 事件引擎结构 4.1 事件队列 4.2 事件处理线程 4.3 事件处理函数字典/通用事件 ...

  7. 消息机制学习笔记(四)—— 内核回调机制

    消息机制学习笔记(四)-- 内核回调机制 要点回顾 内核调用 实验1:理解内核调用 第一步:编译并运行以下代码 第二步:修改窗口过程函数,重新运行 KeUserModeCallback 实验2:在OD ...

  8. Windows消息机制学习笔记(三)—— 消息的接收与分发

    Windows消息机制学习笔记(三)-- 消息的接收与分发 要点回顾 消息循环 消息队列 消息的接收 GetMessage 实验1:理解GetMessage 第一步:编译并运行程序A 第二步:编译并运 ...

  9. Windows消息机制学习笔记(二)—— 窗口与线程

    Windows消息机制学习笔记(二)-- 窗口与线程 要点回顾 消息从哪里来? 实验一:Spy++捕获消息 实验二:消息捕获 消息到哪里去? 窗口在哪? 实验:分析CreateWindowExW 窗口 ...

最新文章

  1. 有人喜欢爱情测试小游戏么
  2. Angularjs 设置全局变量的3种方法
  3. Android开发启动未注册的activity,Hook使用demo
  4. __attribute__ ((__pure__))
  5. comsol圆柱形永磁体_永磁体模拟快速入门
  6. python显示gif图片报错_用Python制作在地图上模拟瘟疫扩散的Gif图
  7. 邓俊辉数据结构学习-7-BST
  8. centos 7 163 yum 源 python 2.7.5
  9. WIN10系统 Indirect Display 虚拟显示器之特殊应用
  10. a标签下载pdf文档
  11. 书摘:刘润《5分钟商学院》之“结果偏见”
  12. 中交一公局二公司全面推进章管家 印章智慧管理转型在即
  13. UI设计中关于按钮的那些事
  14. html修改progress背景色,html5progress标签如何更改进度条颜色?progress进度条详解
  15. 腾讯全民wifi驱动 v1.1.923 官方版
  16. python 了解量化交易
  17. html、css --苏宁官网静态界面
  18. _3_body_标签
  19. Python:NBA球员得分数据排行爬虫
  20. 破解mariadb数据库密码

热门文章

  1. python作业网站_怒刷python作业-WEB资讯专栏-DMOZ中文网站分类目录-免费收录各类优秀网站的中文网站目录....
  2. Win32环境下轻松调试单板安全模式软件下载功能
  3. 推荐系统CTR技术的演变历史
  4. 06.简书项目实战三:详情页面和登录功能实现
  5. 杭州java校园招聘_网易校园招聘杭州Java笔试题
  6. 微软承认部分 Win10 安装 12 月更新后出现 0xc000021a 蓝屏错误
  7. VoLTE, IMS, VOIP, LTE之间的关系
  8. python 爬取天猫店铺商品评论
  9. 华硕主板+ubuntu18.04+3090驱动安装踩坑记录
  10. Rocky Linux更换yum源为国内源