标签+鼠标
QEvent
需求鼠标进入控件范围会进行相关操作
在QEnterEvent类中
cpp
[virtual protected] void QWidget::enterEvent(QEnterEvent *event)
虚成员函数可以进行重写
实现鼠标进入或离开Lable会打印输出
新建一个父类为QWidget的名字为mylable的C++类文件
先声明在.h文件这
cpp
//鼠标进入事件
void enterEvent(QEnterEvent *event);
//鼠标离开事件
void leaveEvent(QEvent *event);
在.cpp文件中实现为
cpp
//鼠标进入事件
void myLable::enterEvent(QEnterEvent *event)
{
qDebug()<<"鼠标进入";
}
//鼠标离开事件
void myLable::leaveEvent(QEvent *event)
{
qDebug()<<"鼠标离开";
}
然后在ui界面拉一个Lable,右键提升为,可以看到标签的基类为QLable,而我们之前创建是基类为QWidget,所以要改为一样的QLable,
三个地方:
头文件
cpp
#include <QLabel>
.h文件中
cpp
class myLable : public QLabel
{
Q_OBJECT
public:
explicit myLable(QWidget *parent = nullptr);
//鼠标进入事件
void enterEvent(QEnterEvent *event);
//鼠标离开事件
void leaveEvent(QEvent *event);
signals:
};
.cpp文件中
cpp
myLable::myLable(QWidget *parent)
: QLabel{parent}
{}
再提升为,把类明myLable粘贴过来,添加,提升为,就可以实现相关打印输出功能了
鼠标事件的重新实现
在QLabel中有Reimplemented Protected Functions
有重新实现的保护函数
和鼠标事件相关的有
cpp
virtual void mouseMoveEvent(QMouseEvent *ev) override
virtual void mousePressEvent(QMouseEvent *ev) override
virtual void mouseReleaseEvent(QMouseEvent *ev) override
先在.h文件中进行声明
cpp
//重写
virtual void mouseMoveEvent(QMouseEvent *ev);//virtual关键字可加可不加
virtual void mousePressEvent(QMouseEvent *ev);
virtual void mouseReleaseEvent(QMouseEvent *ev);
再在.cpp文件中进行重写
cpp
//鼠标按下,想要获取按下的位置或者其他信息,在QMouseEvent *ev里面
void myLable::mousePressEvent(QMouseEvent *ev)
{
//判断鼠标左键按下
if(ev->button() == Qt::LeftButton)
{
qDebug()<<"鼠标左键按下";
//qt中的格式化 arg参数,链式编程,如果是想知道基于屏幕的坐标则为global
QString str = QString("鼠标按下了 x= %1 y= %2 global x = %3 global y = %4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());
qDebug()<<str;
}
else if(ev->button()==Qt::RightButton)
{
qDebug()<<"鼠标右键键按下";
}
}
//鼠标释放
void myLable::mouseReleaseEvent(QMouseEvent *ev)
{
qDebug()<<"鼠标释放";
}
//鼠标移动
void myLable::mouseMoveEvent(QMouseEvent *ev)
{
//鼠标移动是一个连续的过程,因此不能直接==判断, 要用buttons来进行判断
if(ev->buttons() & Qt::LeftButton)
{
qDebug()<<"鼠标左键移动";
}
}
此时鼠标只有按下才会触发移动函数
可以在构造函数中加一句鼠标追踪函数
cpp
myLable::myLable(QWidget *parent)
: QLabel{parent}
{
setMouseTracking(true);//设置鼠标追踪
}
cpp
//鼠标移动
void myLable::mouseMoveEvent(QMouseEvent *ev)
{
//鼠标移动是一个连续的过程,因此不能直接==判断, 要用buttons来进行判断
if(ev->buttons() & Qt::LeftButton)
{
qDebug()<<"鼠标左键移动";
}
qDebug()<<"鼠标追踪移动";
}
标签+定时器
利用事件timerEvent
在Widget中重写
cpp
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//在构造函数中启动定时器
startTimer(1000);//参数1 时间间隔 单位ms
}
Widget::~Widget()
{
delete ui;
}
//定时器
void Widget::timerEvent(QTimerEvent *e)
{
static int num = 1;//变成全局变量
ui->label_2->setText(QString ::number(num++));//int转QString
}
若是想再添加一个Label,以2秒的时间间隔进行定时
定时器开始函数返回值是int类型,是定时器的唯一id号,
cpp
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//在构造函数中启动定时器
this->id1 = startTimer(1000);//参数1 时间间隔 单位ms
this->id2 = startTimer(2000);//以2秒时间间隔运行
}
Widget::~Widget()
{
delete ui;
}
//定时器
void Widget::timerEvent(QTimerEvent *e)
{
if(e->timerId() == id1)
{
static int num1 = 1;//变成全局变量
ui->label_2->setText(QString ::number(num1++));//int转QString
}
if(e->timerId() == id2)
{
static int num2 = 1;//变成全局变量
ui->label_3->setText(QString ::number(num2++));//int转QString
}
}
利用类QTimer
cpp
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//通过事件来操作定时器
//在构造函数中启动定时器
this->id1 = startTimer(1000);//参数1 时间间隔 单位ms
this->id2 = startTimer(2000);//以2秒时间间隔运行
//定时器的第二种方式
QTimer *timer = new QTimer(this);
timer->start(500);//0.5秒发出信号
connect(timer,&QTimer::timeout,this,[=](){
static int num3 = 1;//变成全局变量
ui->label_4->setText(QString ::number(num3++));
});
//也可以实现按下按钮定时器停止,利用 timer->stop();
}
事件分发器
在系统接收到信号时会通过一个事件分发器来管理事件,boo; event(QEvent * ev),返回值是bool类型,为true时说明用户要自己处理这个事件,不向下分发事件,进行事件的拦截。
可以针对鼠标事件进行事件的拦截操作案例
cpp
//拦截鼠标按下
bool myLable::event(QEvent *e)
{
if(e->type() == QEvent::MouseButtonPress)
{
qDebug()<<"阻拦后鼠标按下";
return true;//true代表用户自己处理这个事件,不向下分发
}
//其他事件交给父类处理,默认myLabel的父类是QLabel
return QLabel::event(e);
}
事件过滤器
可以在程序分发到event事件之前再做一次高级拦截
使用有两个步骤:
1、给控件安装事件过滤器'
在构造函数中安装
cpp
//给对应的事件安装事件过滤器,在此案例中叫label
ui->label->installEventFilter(this);//通过这个Widget来安装
2、重写eventfilter()
cpp
//重写eventFilter事件,第一个参数:控件,第二个参数:事件
bool Widget::eventFilter(QObject *watched, QEvent *event)
{
if(watched == ui->label )
{
if(event->type() == QEvent::MouseButtonPress)
{
qDebug()<<"高级拦截按下";
return true;
}
}
//其他默认处理
return QWidget::eventFilter(watched,event);
}