c++ qt–事件过滤(第七部分)
一.为什么要用事件过滤
上一篇博客中我们用到了事件来进行一些更加细致的操作,如监控鼠标的按下与抬起,但是我们发现如果有很多的组件那每个组件都要创建一个类,这样就显得很麻烦,所以我们就可以引入事件过滤了,事件过滤不需要创建类,只需要安装过滤器然后重写过滤器函数就可以了
二.写一个使用了事件过滤例子
1.所用到组件如下
这里还用到了栅格布局
2.安装过滤器
在mainwindow.cpp的构造函数中写下面代码
ui->lineEdit->installEventFilter(this/*参数得是对象*/);//安装过滤器,相当于某个组件安装监控,查看的权力交给MainWindow(物业)
ui->plainTextEdit->installEventFilter(this);//安装过滤器,相当于某个组件安装监控,查看的权力交给MainWindow(物业)
3.重写过滤器函数
1.声明
在mainwindow.h的类中写下面代码
public:
bool eventFilter(QObject *watched, QEvent *event);
2.定义
在mainwindow.cpp中写下面代码
bool MainWindow::eventFilter(QObject *watched, QEvent *event){
if(watched==ui->lineEdit){//如果是密码组件
if(event->type()/*获取事件的类型*/==QEvent::KeyPress){//如果是键盘按下的事件
QKeyEvent* pKey=(QKeyEvent*)event;//相当于是强转成具体事件的指针
if(pKey->key()>=Qt::Key_A&&pKey->key()<=Qt::Key_Z){//如果是字母
qDebug()<<"放行"<<pKey->key();
return false;//不过滤,(放行)
}
else{
qDebug()<<"过滤"<<pKey->key();
return true;//过滤(不放行)
}
}
}
else if(watched==ui->plainTextEdit){//如果是多行文本输入框
if(event->type()==QEvent::Wheel){//如果是滑轮按下的事件
QWheelEvent* pWheel =(QWheelEvent*)event;//相当于是强转成具体事件的指针
if(pWheel->buttons()==Qt::MidButton){//如果按下鼠标中间
qDebug()<<"x == "<<pWheel->angleDelta().x();//alt+上:y=120 alt+下:y=-120
qDebug()<<"y == "<<pWheel->angleDelta().y();//上:y=120 下:y=-120
int y=pWheel->angleDelta().y();
if(y>0){
ui->plainTextEdit->zoomIn();//放大
}
else if(y<0){
ui->plainTextEdit->zoomOut();//缩小
}
return true;//过滤(不放行),事件在这里已经被处理了,没必要继续分发了
}
}
}
return QMainWindow::eventFilter(watched,event);
}
三.写一个给两个数进行运算的例子(自定义事件)
1.用到的组件如下
这里还用到了栅格布局
2.给使用的Combo Box组件(下拉框)加上计算的规则,+ - * /
在mainwindow.cpp的构造函数中写下面代码
QStringList list={"+","-","*","/"};
ui->comboBox->addItems(list);
3.通过点击按钮(计算),进行计算操作
1.添加信号槽
2.声明槽函数(对点击按钮后做出反应的函数)
在mainwindow.h的类中
private slots://使用qt中自带的方法添加槽函数,会自动添加声明,信号与槽函数的连接也会帮你写好,这里我没有展示代码
void on_pushButton_clicked();
3.创建一个类文件(用来自定义事件)
4.修改类
在myevent.h中进行的修改
在myevent.cpp中进行的修改
5.在类中添加属性
在myevent.h中的类中写下面代码
public:
int m_a;
int m_b;
QString m_str;
6.再建一个窗口用来接收事件
1.创建窗口
2.此窗口使用的组件如下
3.定义一个对象
在main.cpp中写下面代码
在全局定义一个指针来指向对象
Dialog* pDlg=nullptr;
在main函数中定义对象
Dialog dia;
pDlg=&dia;//指针指向对象
7.定义槽函数
在mainwindow.cpp中写下面代码
QEvent::Type myType=QEvent::User;//自定义事件的ID (1000)
void MainWindow::on_pushButton_clicked()
{
//获得两个数字 和 规则
int a=ui->spinBox->value();
int b=ui->spinBox_2->value();
QString str=ui->comboBox->currentText();
//自定义事件,并携带信息
//MyEvent myEve(myType);//定义一个对象
myEve.m_a=a;
myEve.m_b=b;
myEve.m_str=str;
//发射自定义事件
extern Dialog* pDlg;//外部声明,可以让变量进行跨文件使用
//第一种方法
//下面函数发送事件,是阻塞的,等待对方处理完毕后,再返回,继续执行下面的代码(类似于打电话)
//QCoreApplication::sendEvent(pDlg,&myEve);//发送自定义事件
//qDebug()<<"sendEvent over";
//第二种方法
MyEvent* pEve=new MyEvent(myType);//在堆区创造一个对象,防止此函数结束对象被回收
pEve->m_a=a;
pEve->m_b=b;
pEve->m_str=str;
//发送事件,非阻塞,投递完之后立即返回继续执行下面的代码(类似于发短信)
QCoreApplication::postEvent(pDlg,pEve);
qDebug()<<"postEvent over";
}
8.重写接收自定义事件并进行处理的函数
1.声明
在dialog.h中写下面代码
public:
virtual void customEvent(QEvent *event);
2.定义
在dialog.cpp中写下面代码
void Dialog::customEvent(QEvent *event)
{
extern QEvent::Type myType;//外部声明,可以让变量进行跨文件使用
if(event->type()==myType){
MyEvent* pEve=(MyEvent*)event;//强转为自定义事件
int res=0;//结果
if(pEve->m_str=="+"){
res=pEve->m_a+pEve->m_b;
}
else if(pEve->m_str=="-"){
res=pEve->m_a-pEve->m_b;
}
else if(pEve->m_str=="*"){
res=pEve->m_a*pEve->m_b;
}
else if(pEve->m_str=="/"){
res=pEve->m_a/pEve->m_b;
}
ui->label->setText(QString("规则:%1,结果%2").arg(pEve->m_str).arg(res));
this->show();
}
qDebug()<<"处理自定义事件完毕";