QT6(事件与信号及事件过滤器)
QT6
事件与信号
- 界面组件类的很多信号可以看作是对某些事件的封装,例如QPushButton的clicked()信号,可以看做是对QEvent:;MouseButtonRelease类型事件的封装
- 但是Qt的界面组件只是装少数事件封装成了信号。例如,QLabel就没有与鼠标双击事件对应的信号,可以从QLabel派生一个类,把鼠标双击事件转换为一个自定义信号doubleClicked(),即将mouseDoubleClickEvent事件封装为doubleClicked()信号
我们需要给一个QLabel组件添加双击和鼠标移动上去就变颜色的方法,由于默认的QLabel组件没有这两个方法,所以我们要给它添加这两个自定义的事件方法
-
创建一个类用来实现自定义的信号和方法
-
添加我们刚刚创建好的类,这样我们就可以在我们自己定义的类上添加自定义的信号和方法
选择添加,添加上去后再选择点提升
这样这边显示的类就为我们自己定义的类了
- TMyLabel.h代码完善
#ifndef TMYLABEL_H
#define TMYLABEL_H#include <QLabel>
#include <QObject>class TMyLabel : public QLabel
{Q_OBJECT
public:TMyLabel(QWidget *parent = nullptr);
// 自定义信号
signals:// 双击void doubleClicked();// 重载mouseDoubleClickEvent
protected:virtual void mouseDoubleClickEvent(QMouseEvent *event) override;// 重载event
public:virtual bool event(QEvent *event) override;
};#endif // TMYLABEL_H
- MyLabel.cpp代码完善
#include "tmylabel.h"
#include <QEvent>
TMyLabel::TMyLabel(QWidget* parent):QLabel(parent) {// 启用鼠标悬停事件跟踪setAttribute(Qt::WA_Hover,true);}void TMyLabel::mouseDoubleClickEvent(QMouseEvent *event)
{Q_UNUSED(event);// 发出信号emit doubleClicked();
}bool TMyLabel::event(QEvent *event)
{// 判断事件的肉类是否是我们需要的鼠标事件if(event->type() == QEvent::HoverEnter){QPalette plet = this->palette();plet.setColor(QPalette::WindowText,Qt::red);this->setPalette(plet);}else if(event->type() == QEvent::HoverLeave){QPalette plet = this->palette();plet.setColor(QPalette::WindowText,Qt::black);this->setPalette(plet);}return QLabel::event(event);
}
- Main.cpp中使用我们自定义的信号
#include "widget.h"
#include "./ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// 发送我们TMyLabel类中的信号connect(ui->label,&TMyLabel::doubleClicked,this,&Widget::do_double_click);
}Widget::~Widget()
{delete ui;
}void Widget::do_double_click()
{ui->label->setText("标签被点击了,信号槽得到响应");ui->label->adjustSize();
}void Widget::mouseDoubleClickEvent(QMouseEvent *event)
{Q_UNUSED(event);ui->label->setText("窗口被艰双击了!");ui->label->adjustSize();
}
效果展示
事件过滤器
- 事件过滤器是QObjcet提供的一种处理事件的方法
- 它将一个对象的事件委托给另一个对象来监视并处理
当我们想要为一个QLabel添加一个鼠标的事件时,但我们又不想去添加一个新的派生类时,就可以使用委托的方式(比如委托给我们的QWidget来处理)
installEventFilter想要委托的方法
void QObject::installEventFilter(QObject* filterObj)
eventFilter处理委托的方法
virtual bool QObject::eventFilter(QObject* watched,QEvent* event)
代码测试
#include "widget.h"
#include "./ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// 委托事件ui->label->installEventFilter(this);ui->label_2->installEventFilter(this);
}Widget::~Widget()
{delete ui;
}// 对委托事件处理
bool Widget::eventFilter(QObject *watched, QEvent *event)
{if(watched == ui->label){if(event->type() == QEvent::Enter){ui->label->setStyleSheet("background-color:rgb(170,255,255);");}else if(event->type() == QEvent::Leave){ui->label->setText("单击我");ui->label->setStyleSheet("");}else if(event->type() == QEvent::MouseButtonPress){ui->label->setText("按键被按下");}else if(event->type() == QEvent::MouseButtonRelease){ui->label->setText("按键被松开");}}if(watched == ui->label_2){if(event->type() == QEvent::Enter){ui->label_2->setStyleSheet("background-color:rgb(85,255,127);");}else if(event->type() == QEvent::Leave){ui->label_2->setText("双击我");ui->label_2->setStyleSheet("");}else if(event->type() == QEvent::MouseButtonDblClick){ui->label_2->setText("按键被双击");}}return QWidget::eventFilter(watched,event);
}
效果展示