目录
- 1.定时器
- 0.是什么?
- 1.QTimerEvent
- 2.QTimer
- 3.获取系统⽇期及时间
- 2.事件分发器
- 1.概述
- 2.事件分发器工作原理
- 3.使用
- 3.事件过滤器
- 0.是什么?
- 2.使用
1.定时器
0.是什么?
- 在进⾏窗⼝程序的处理过程中,经常要周期性的执⾏某些操作,或者制作⼀些动画效果,使⽤定时器就可以实现
- 定时器:就是在间隔⼀定时间后,去执⾏某⼀个任务
- Qt中的定时器分为
QTimerEvent
和QTimer
这2个类
1.QTimerEvent
QTimerEvent
:⽤来描述⼀个定时器事件- 使用:
startTimer()
:开启⼀个定时器- 参数:以毫秒为单位的整数作为参数来表明设定的时间
- 返回值:一个整形的身份标识,代表这个定时器
- 当定时器溢出时(即定时时间到达)就可以在
timerEvent()
中获取该定时器的编号来进⾏相关操作 killTimer
:关闭定时器
- 注意:如果一个程序中存在多个定时器(
startTimer
创建的定时器),此时每个定时器都会触发timerEvent()
- 示例:
// 构造函数中 { // 开启定时器事件. // 此处 timerId 是一个定时器的身份标识. timerId = this->startTimer(1000); } void Widget::timerEvent(QTimerEvent* event) { // 先判定一下这次触发是否是想要的定时器触发的. if (event->timerId() != this->timerId) { return; } int value = ui->lcdNumber->intValue(); if (value <= 0) { // 停止定时器 this->killTimer(this->timerId); return; } value -= 1; ui->lcdNumber->display(value); }
2.QTimer
QTimer
底层是QTimerEvent
QTimer
:实现⼀个定时器,它提供了更⾼层次的编程接⼝- 如:可以使⽤信号和槽,还可以设置只运⾏⼀次的定时器
- 示例:
QTimer* timer = new QTimer(this); connect(ui->btn1, &QPushButton::clicked, [=](){ timer->start(1000); }); connect(timer, &QTimer::timeout, [=](){ static int num = 1; ui->label->setText(QString::number(num++)); }); connect(ui->btn2, &QPushButton::clicked, [=](){ timer->stop(); });
3.获取系统⽇期及时间
-
在Qt中,获取系统的⽇期及实时时间可以通过
QTimer
类和QDateTime
类 -
QDateTime
类提供了字符串格式的时间,输出格式由toString()
⽅法中的format
参数列表决定 -
示例:
// 构造函数中 { QTimer* timer = new QTimer(this); connect(ui->btn1, &QPushButton::clicked, [=](){ timer->start(1000); }); connect(ui->btn2, &QPushButton::clicked, [=](){ timer->stop(); }); connect(timer, &QTimer::timeout, this, &Widget::TimeUpdate); } void Widget::TimeUpdate() { QString t = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); ui->label->setText(t); }
2.事件分发器
1.概述
- 在Qt中,事件分发器(
EventDispatcher
)是⼀个核⼼概念,⽤于处理GUI应⽤程序中的事件- 属于Qt事件机制背后的一些逻辑
- 杀伤力比较广,不当使用可能对现有逻辑造成一些负面影响,一般不建议使用
- 事件分发器负责将事件从⼀个对象传递到另⼀个对象,直到事件被处理或被取消
- 每个继承⾃
QObject
类或QObject
类本⾝都可以在本类中重写bool event(QEvent* e)
,来实现相关事件的捕获和拦截
2.事件分发器工作原理
- 在Qt中,发送的事件都是传给了
QObject
对象,更具体点是传给了QObject
对象的event()
- 所有的事件都会进⼊到这个函数⾥⾯
- 那么处理事件就要重写这个
event()
函数
- 那么处理事件就要重写这个
event()
函数本⾝不会去处理事件,⽽是根据事件类型(type
)调⽤不同的事件处理函数
- 所有的事件都会进⼊到这个函数⾥⾯
- 事件分发器就是⼯作在应⽤程序向下分发事件的过程中
- 事件分发器⽤于分发事件,在此过程中,事件分发器也可以做拦截操作
- 事件分发器主要是通过
bool event(QEvent* e)
来实现- 返回值:若为
ture
,代表拦截,不向下分发
- 返回值:若为
3.使用
-
Qt中的事件是封装在
QEvent
类中,其所包括的事件类型: -
示例:拦截鼠标左键单击事件
void Widget::mousePressEvent(QMouseEvent* event) { if(event->button() == Qt::LeftButton) { qDebug() << "鼠标左键被按下"; } } bool Widget::event(QEvent* ev) { if(ev->type() == QEvent::MouseButtonPress) { qDebug() << "Event中鼠标被按下"; return true; // 返回true,代表拦截,不向下分发 } // 其他事件交给父类处理(默认处理) return QWidget::event(ev); }
3.事件过滤器
0.是什么?
- 在Qt中,⼀个对象可能经常要查看或拦截另外⼀个对象的事件
- 例如:对话框想要拦截按键事件,不让别的组件接收到,或者修改按键的默认值等
- 属于Qt事件机制背后的一些逻辑
- 杀伤力比较广,不当使用可能对现有逻辑造成一些负面影响,一般不建议使用
- Qt创建了
QEvent
事件对象之后,会调⽤QObject
的event()
函数处理事件的分发,可以在event()
函数中实现拦截的操作- 由于
event()
是protected
的,因此,需要继承已有类 - 如果组件很多,就需要重写很多个
event()
- 这当然相当⿇烦,更不⽤说重写
event()
还得⼩⼼⼀堆问题 - 好在Qt提供了另外⼀种机制来达到这⼀⽬的:事件过滤器
- 这当然相当⿇烦,更不⽤说重写
- 由于
- 事件过滤器是在应⽤程序分发到
event
事件分发器之前,再做⼀次更⾼级的拦截
2.使用
- 事件过滤器的⼀般使⽤步骤:
- 安装事件过滤器
- 重写事件过滤器函数:
eventfilter()
- 示例:
{ void MyLabel::mousePressEvent(QMouseEvent* event) { QString str = QString("鼠标按下: x = %1, y = %2"). arg(event->x()).arg(event->y()); qDebug() << str.toUtf8().data(); } void MyLabel::event(QEvent* ev) { if(ev->type() == QEvent::MouseButtonPress) { QMouseEvent* event = static_cast<QMouseEvent* e>(e); QString str = QString("event中鼠标按下: x = %1, y = %2"). arg(event->x()).arg(event->y()); qDebug() << str.toUtf8().data(); return true; // 返回true,代表拦截,不向下分发 } // 其他事件交给父类处理(默认处理) return QWidget::event(ev); } } ---------------------------------------------------------------------- { // Widget构造函数中 { // 步骤1:给label安装事件过滤器 this:当前窗口安装事件过滤器 ui->label->installEventFilter(this); } // 步骤2:重写eventFilter事件 bool Widget::eventFilter(QObject* obj, QEvent* e) { if(obj == ui->label) // 判断控件 { if(e->type == QEvent::MouseButtonPress) { QMouseEvent* event = static_cast<QMouseEvent* e>(e); QString str = QString("事件过滤器中鼠标按下: x = %1, y = %2"). arg(event->x()).arg(event->y()); qDebug() << str.toUtf8().data(); return true; } } // 其他事件交给父类处理 return QWidget::event(ev); } }