事件过滤器的使用
事件是发生在widget中,也就是父类窗口中
并不能发生在label中,如果想要让事件发生在label中,就必须通过一个叫做事件过滤器
的东西,将父窗口中的事件派发给label窗口
用到的一个Qt功能叫做提升为
该功能作用:让我们能够深度自定义某个官方控件
提升为步骤
1、先构建一个正常的qt widget项目
2、自定义一个label让他继承自QLabel
3、将label控件提升为mylabel类型
4、重写事件过滤器即可
例子:利用事件过滤器,使得键盘事件可以派发给label中,并且输入键盘时将按键的值写进label中,按下 Backspace或者Delete时删除一个字母,按下ctrl+c时复制内容,ctrl+v在文本框后面粘贴,ctrl+x剪切文本框内容
并且在按下组合键时在下方debug打印对应组合键
过滤器使用说明已经在代码中进行注释
mylabel.h
#ifndef MYLABEL_H
#define MYLABEL_H
#include<QLabel>
#include<QKeyEvent>
#include<QDebug>
class mylabel : public QLabel
{
public:
mylabel(QWidget* parent = 0);
private:
QString copy;
protected:
virtual void keyPressEvent(QKeyEvent *ev);
virtual bool eventFilter(QObject *watched, QEvent *event);
};
#endif // MYLABEL_H
mtlabel.cpp
#include "mylabel.h"
mylabel::mylabel(QWidget* parent):
QLabel(parent)
{
}
void mylabel::keyPressEvent(QKeyEvent *ev)
{
QString str;
//按backspace和delete 删除一个
if(ev->key() == Qt::Key_Backspace||ev->key() == Qt::Key_Delete){
qDebug()<<"delete";
str = this->text();
str.chop(1); //删除一个
this->setText(str);
}else if(ev->modifiers() == Qt::ControlModifier &&ev->key() == Qt::Key_C){
qDebug()<<"ctrl+c";
copy.clear();//先情况copy中的内容
copy = this->text(); //将label中的文字获取到copy中
}else if(ev->modifiers() == Qt::ControlModifier &&ev->key() == Qt::Key_V){
qDebug()<<"ctrl+v";
str = this->text()+copy;
this->setText(str);
}else if(ev->modifiers() == Qt::ControlModifier &&ev->key() == Qt::Key_X){
qDebug()<<"ctrl+x";
copy.clear();
copy = this->text();
this->clear();
}else{
//按键盘输入键盘字母r
str = this->text()+ev->text();
this->setText(str);
}
}
bool mylabel::eventFilter(QObject *watched, QEvent *event)
{
//watched:事件派发方指针
//event:派发过来的具体事件,一般而言,只要父控件安装了事件过滤器,所有事件都会派发过来
//返回值
//ture: 代表接受当前事件之后不再接受其他事件
//false: 代表接受完当前事件之后,等待下一次事件的接受
//①判断事件的派发方是否为当前的父控件
if(watched == this->parent()){
//②如果事件的派发方时当前控件的父控件的化,继续判断派发过来的控件是否为键盘事件
if(event->type() == QEvent::KeyPress){
//到此为止,event代表了父控件发过来的键盘点击事件,所以,这里可以直接通过键盘点击事件区调用label的keyPressEvent
//或者直接写其他想要的逻辑
//c风格 mylabel::keyPressEvent((QKeyEvent *)event);
//c++风格 dynamic_cast<QKeyEvent*> 等效于 (QKeyEvent *)
mylabel::keyPressEvent(dynamic_cast<QKeyEvent*>(event));
return true;
}
}
return false;
/*if里面返回ture或者false都无所谓
但是if外面的返回值必须返回false
返回false代表当前事件接受完毕,等待下一次事件的接受
事件过滤器所有的事情都会派发,如果if外面的返回值返回true的话代表当前的事件接受完毕,不接受下一个事件,如果第一个事件不是键盘事件,那么就不会接受其他事件*/
}
widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
//事件过滤器
this->installEventFilter(ui->label);
}
Widget::~Widget()
{
delete ui;
}
运行效果