Qt桌面应用开发 第六天(鼠标事件 定时器事件 定时器类 事件分发器 事件过滤器)
目录
1.1鼠标进入和离开enterEvent\leaveEvent
1.2鼠标按下释放和移动mousePressEvent\mouseReleaseEvent\mouseMoveEvent
1.3定时器事件timerEvent
1.4定时器类QTimer
1.5事件分发器event
1.6事件过滤器eventFilter
1.1鼠标进入和离开enterEvent\leaveEvent
事件:
鼠标进入函数原型:
[virtual protected] void QWidget::enterEvent(QEvent* event);
鼠标离开函数原型:
[virtual protected] void QWidget::leaveEvent(QEvent* event);
举例:重写鼠标进入离开事件
void MyLable::enterEvent(QEvent *event)
{
qDebug()<<"鼠标进入";
}
void MyLable::leaveEvent(QEvent *event)
{
qDebug()<<"鼠标离开";
}
1.2鼠标按下释放和移动mousePressEvent\mouseReleaseEvent\mouseMoveEvent
鼠标按下、释放是瞬间触发的,移动是一个持续性事件
鼠标按下函数原型:
[virtual protected] void QWidget::mousePressEvent(QMouseEvent* event);
鼠标释放函数原型:
[virtual protected] void QWidget::mouseReleaseEvent(QMouseEvent* event);
鼠标移动函数原型:
[virtual protected] void QWidget::mouseMoveEvent(QMouseEvent* event);
举例:
void MyLable::mousePressEvent(QMouseEvent *event)
{
qDebug()<<"鼠标按下了";
}
void MyLable::mouseReleaseEvent(QMouseEvent *event)
{
qDebug()<<"鼠标松开了";
}
void MyLable::mouseMoveEvent(QMouseEvent *event)
{
qDebug()<<"鼠标移动了";
}
扩展1:鼠标按下,释放,移动时,分别打印鼠标相对于Label的x、y坐标
QMouseEvent可以获取鼠标对应的信息
void MyLable::mousePressEvent(QMouseEvent *event)
{
QString str=QString("x=%1,y=%2").arg(event->x()).arg(event->y());
qDebug()<<str;
qDebug()<<"鼠标按下了";
}
void MyLable::mouseReleaseEvent(QMouseEvent *event)
{
QString str=QString("x=%1,y=%2").arg(event->x()).arg(event->y());
qDebug()<<str;
qDebug()<<"鼠标松开了";
}
void MyLable::mouseMoveEvent(QMouseEvent *event)
{
QString str=QString("x=%1,y=%2").arg(event->x()).arg(event->y());
qDebug()<<str;
qDebug()<<"鼠标移动了";
}
扩展2:在MyLabel中鼠标只要移动,就会触发移动事件,不需要按下
将鼠标追踪效果设为true
MyLable::MyLable(QWidget *parent)
: QLabel{parent}
{
this->setMouseTracking(true);
}
扩展3:鼠标左键按下时,才会触发相应内容
QMouseEvent对象的button()可以判断鼠标按下的是左键或右键
void MyLable::mousePressEvent(QMouseEvent *event)
{
if(Qt::LeftButton==event->button())
{
QString str=QString("x=%1,y=%2").arg(event->x()).arg(event->y());
qDebug()<<str;
qDebug()<<"鼠标按下了";
}
}
void MyLable::mouseReleaseEvent(QMouseEvent *event)
{
if(Qt::LeftButton==event->button())
{
QString str=QString("x=%1,y=%2").arg(event->x()).arg(event->y());
qDebug()<<str;
qDebug()<<"鼠标松开了";
}
}
void MyLable::mouseMoveEvent(QMouseEvent *event)
{
if(Qt::LeftButton==event->button())
{
QString str=QString("x=%1,y=%2").arg(event->x()).arg(event->y());
qDebug()<<str;
qDebug()<<"鼠标移动了";
}
}
1.3定时器事件timerEvent
需求:两个label,初始值都为1,第一个每隔一秒加一,第二个每隔一秒加二
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
//重写定时器事件
void timerEvent(QTimerEvent *event);
//声明两个定时器的唯一标识
int id1;
int id2;
private:
Ui::Widget *ui;
};
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//1000毫秒,每隔一秒钟会触发timerEvent,startTimer会返回一个唯一标识
this->id1=startTimer(1000);
this->id2=startTimer(2000);
}
void Widget::timerEvent(QTimerEvent *event)
{
//QTimerEvent的timerId方法可以获得计时器的唯一标识
if(event->timerId()==this->id1)
{
static int num1=1;
ui->label->setText(QString::number(num++));
}
if(event->timerId()==this->id2)
{
static int num2=1;
ui->label->setText(QString::number(num2++));
}
}
startTimer——启动定时器,单位是毫秒,startTimer会返回一个int类型的唯一标识
1.4定时器类QTimer
需求:一个label,初始值为1,每隔0.5秒加一;且有一个停止按钮,点击之后,label上的数字停止递增
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
QTimer * timer=new QTimer(this);
//每隔500毫秒发timeout的信号
timer->start(500);
connect(timer,&QTimer::timeout,[=]{
static int num3=1;
ui->label_3->setText(QString::number(num++));
})
connect(ui->btn_stop,&QPushButton::clicked,[=]{
timer->stop();
});
}
注意:
- start——启动定时器,单位毫秒;超过时间会发timeout的信号
- stop——停止计时器
1.5事件分发器event
需求:重写一个事件分发器,拦截鼠标按下事件
class MyLabel : public QLabel
{
Q_OBJECT
public:
explicit MyLabel(QWidget *parent = nullptr);
void mousePressEvent(QMouseEvent *ev);
bool event(QEvent *e);
signals:
};
void MyLabel::mousePressEvent(QMouseEvent *ev)
{
QString str=QString("鼠标按下了x=%1,y=%2").arg(ev->x()).arg(ev->y());
qDebug()<<str;
}
bool MyLabel::event(QEvent *e)
{
if(e->type()==QEvent::MouseButtonPress)
{
QMouseEvent* ev=static_cast<QMouseEvent*>(e);
QString str=QString("event事件中鼠标按下了x=%1,y=%2").arg(ev->x()).arg(ev->y());
qDebug()<<str;
//标识拦截下鼠标按下事件
return true;
}
//其他事件交给父类处理
return QLabel::event(e);
}
1.6事件过滤器eventFilter
时间过滤器函数原型:
virtual bool QObject::eventFilter(QObject* watched,QEvent* event);
若此事件是感兴趣的类型,返回true,自己进行处理;若不是,返回false,继续转发
事件过滤器使用步骤:
- 给控件安装过滤器installEventFilter
- 重写过滤器事件eventFilter
//安装事件过滤器
ui->label->installEventFilter(this);
bool Widget::eventFilter(QObject *watched, QEvent *event)
{
if(watched==ui->label)
{
if(event->type()==QEvent::MouseButtonPress)
{
QMouseEvent* ev=static_cast<QMouseEvent*>(event);
QString str=QString("eventFilter事件中鼠标按下了x=%1,y=%2").arg(ev->x()).arg(ev->y());
qDebug()<<str;
//标识拦截下鼠标按下事件
return true;
}
}
//其他事件交给父类处理
return QWidget::eventFilter(watched,event);
}