QT实战 之事件和定时器
QT实战 之事件和定时器
- 自定义控件MyLabel,继承自QLabel(创建时继承自QWidget,创建好后再修改成QLabel)
- 拖拽Label控件到主界面,然后将该控件提升为MyLabel(注意必须用MyLabel的直接父类进行提升,如果用Widget则无法进行提升)
- 在MyLabel头文件中中声明重写事件
- 在MyLabel源文件中重写事件
- 重写event事件,可以过滤指定的事件,而不派发到具体的事件中
- 在Widget中为MyLabel安装事件过滤器EventFilter,也可以过滤事件
- 在Widget中重写timerEvent,可以启动定时任务
- 在Widget中启动定时器startTimer,可以自动调用timerEvent事件
- startTimer返回定时器的ID,可以启动多个定时器,执行多个定时任务
- 在timerEvent事件中,按照不同的ID,来区分不同的定时器,从而执行不同的任务
- 可以使用QTimer类启动定时任务,需要用connect函数将定时器的timeout信号和槽函数进行连接
- QTimer类比用timerEvent更加灵活方便,也无需定义全局变量ID区分不同的定时器
- 注意static int num=1因为是全局静态变量,只会声明一次,因此该语句只会执行一次
#include "widget.h" #include "ui_widget.h" #include<QMouseEvent> #include<QDebug> #include<QString> #include<QTimer> Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); //为控件安装事件过滤器 ui->label-> installEventFilter(this);
//定时方法1:用定时器事件进行定时操作 timerId1= startTimer(1000);//定时器 每秒增加1 timerId2=startTimer(2000);//定时器 每2秒增加1 timerId3=startTimer(500);//定时器 每0.5秒增加1
//定时方法2:用定时器对象QTimer进行定时操作 QTimer* timer=new QTimer(this);//用定时器对象进行定时 timer->start(200);//每0.2秒增加1 connect(timer,&QTimer::timeout,this,[=](){ //静态全局变量的声明,只会执行一次 static int num4=1; ui->label_4->setText(QString::number(num4++)); }); } //重写定时器事件 void Widget::timerEvent(QTimerEvent * e) { //静态全局变量的声明,只会执行一次 static int num1=1; static int num2=1; static int num3=1; if(e->timerId()==timerId1) { ui->label->setText(QString::number(num1++)); } if(e->timerId()==timerId2) { ui->label_2->setText(QString::number(num2++)); } if(e->timerId()==timerId3) { ui->label_3->setText(QString::number(num3++)); } } Widget::~Widget() { delete ui; } //使用eventFilter拦截事件 bool Widget::eventFilter(QObject *obj, QEvent *e) { // 判定对象 if(obj==ui->label) { // 判定事件类型 if(e->type()==QEvent::MouseButtonPress) { QMouseEvent *ev=static_cast<QMouseEvent*>(e); //用%拼接字符串 QString str=QString("eventFilter: x=%1 y=%2 globalX=%3 globalY=%4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY()); qDebug()<<str; return true;//true表示处理完毕,不再向下分发 }
} // 其他情况使用默认处理方式 return QWidget::eventFilter(obj,e); }
|
#include "mylabel.h" #include<QDebug> #include<QString> #include<QMouseEvent> MyLabel::MyLabel(QWidget *parent) : QLabel(parent) { // 设置鼠标追踪(在鼠标没有按下的情况下,也可以追踪鼠标的移动) setMouseTracking(true);
} //鼠标进入事件 void MyLabel:: enterEvent(QEvent* ) { qDebug()<<"鼠标进入";
} //鼠标离开事件 void MyLabel:: leaveEvent(QEvent*) { qDebug()<<"鼠标离开"; } //鼠标移动事件(默认按下鼠标键,才会调用;如果设置了鼠标追踪,则鼠标一移动,就会调用) void MyLabel:: mouseMoveEvent(QMouseEvent *ev) {
qDebug()<<"鼠标移动了"; } //鼠标按下事件 void MyLabel::mousePressEvent(QMouseEvent *ev) { //判断按下的鼠标按键 if(ev->button()==Qt::LeftButton) { //用%拼接字符串 QString str=QString("mousePressEvent x=%1 y=%2 globalX=%3 globalY=%4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY()); qDebug()<<str; } } //鼠标抬起事件 void MyLabel::mouseReleaseEvent(QMouseEvent *ev) { //判定抬起的是那个按键 if(ev->button()==Qt::RightButton) { //用%拼接字符串 QString str=QString("mouseReleaseEvent x=%1 y=%2 globalX=%3 globalY=%4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY()); qDebug()<<str; }
}
//事件分发器event,可以拦截事件;或自动分发事件; bool MyLabel::event(QEvent *e) { //如果是鼠标按下事件,就自己处理,不向下分发 if(e->type()==QEvent::MouseButtonPress) { QMouseEvent *ev=static_cast<QMouseEvent*>(e); //用%拼接字符串 QString str=QString("event: x=%1 y=%2 globalX=%3 globalY=%4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY()); qDebug()<<str; return true;//true表示处理完毕,不再向下分发 } return QLabel::event(e);//对于其他事件由父类的event进行默认处理 }
|