Qt中eventFilter()事件过滤器

QObject 有一个 eventFilter() 函数,用于建立事件过滤器。这个函数的签名如下:

virtual bool QObject::eventFilter(QObject* watched, QEvent* event);

事件过滤器的原理:它会检查接收到的事件。如果这个事件是我们感兴趣的类型,就进行我们自己的处理;如果不是,就继续转发。这个函数返回一个 bool 类型,如果你想将参数 event 过滤出来,比如,不想让它继续转发,就返回 true,否则返回 false。

举例:这里使用eventFilter事件过滤器来捕获鼠标对ui中按键的一些操作,比如放在上面,离开

ui->btn_record->installEventFilter(this);
ui->pushButton_player->installEventFilter(this);
ui->pushButton_delete->installEventFilter(this);
ui->pushButton_allCheck->installEventFilter(this);
ui->tableWidget_2->viewport()->installEventFilter(this); //注册事件过滤器

eventFilter() 函数相当于创建了过滤器,然后我们需要安装这个过滤器。上面就是给每个按键以及tablewidget都装上事件过滤器

类一定要继承于Q_OBJECT,并且在类的.h文件中说明这个函数 bool eventFilter(QObject *obj, QEvent *ev);然后在.cpp文件实现该函数

bool record::eventFilter(QObject *obj, QEvent *ev)
{
if (obj == ui->tableWidget_2->viewport()) {
if (ev->type() == QEvent::MouseButtonRelease)
{
QList items1 = ui->tableWidget_2->selectedItems();
if(!items1.isEmpty())
{
int count = items1.count();//获取该行的成员数
int row = ui->tableWidget_2->row(items1.at(0));// 获取该行的行号
QString call_log = "record tableWidget_2 row: " + QString::number(row);
log_filesave(call_log);
ui->lineEdit->setText(SchNameList.at(row));
ui->tableWidget_2->hide();
return true;
}
}
}

if(obj == ui->btn_record) //按键的事件
{
if(ev->type() == QEvent::HoverEnter) //鼠标放在按键上面
{
set_btnState(BTN_RECORD_BTN, BTN_RECORD_STATE_MOUSEOVER);
m_recordBtnUartState = get_btnState(BTN_RECORD_BTN);
return true;
}
else if(ev->type() == QEvent::HoverLeave) //鼠标离开按键
{
set_btnState(BTN_RECORD_BTN, m_recordBtnUartState);
return true;
}
}
return false;
}
//设置按键的状态,比如设置按键的背景
void record::set_btnState(E_BTN_RECORD_NAME buttonName, E_BTN_RECORD_STATE buttonState)
{
switch(buttonName)
{
case BTN_RECORD_BTN:
switch(buttonState)
{
case BTN_RECORD_STATE_NORMAL:
ui->btn_record->resize(NAVI_BTN_NORMAL_W, NAVI_BTN_NORMAL_H);
ui->btn_record->move(NAVI_BTN_NORMAL_X, NAVI_BTN_NORMAL_Y);
ui->btn_record->setStyleSheet("QPushButton{background-image: url(:/public/normalP/conf_menu.png);}");
break;
case BTN_RECORD_STATE_MOUSEOVER:
ui->btn_record->resize(NAVI_BTN_NORMAL_W, NAVI_BTN_NORMAL_H);
ui->btn_record->move(NAVI_BTN_NORMAL_X, NAVI_BTN_NORMAL_Y);
ui->btn_record->setStyleSheet("QPushButton{background-image: url(:/public/mouseoverP/conf_menu.png);}");
break;
case BTN_RECORD_STATE_SELECTED:
ui->btn_record->resize(NAVI_BTN_SELECTED_W, NAVI_BTN_SELECTED_H);
ui->btn_record->move(NAVI_BTN_SELECTED_X, NAVI_BTN_SELECTED_Y);
ui->btn_record->setStyleSheet("QPushButton{background-image: url(:/public/selectedP/conf_menu.png);}");
}
break;
}
}

实际上任何子类都可以使用事件过滤器,不管是不是组件还是类

else if(obj == callnum)
{
if(ev->type() == QEvent::MouseButtonRelease)
{
QMouseEvent * e = static_cast(ev);
int mouseRelease_x = e->x();
int mouseRelease_y = e->y();
int currrnt_pos = 0, last_pos;
for(int k=0;k<16;k++) //检索呼叫列表是否有占用当前窗口
{
if((mouseRelease_x > (callnum->button[k]->pos().x())) && (mouseRelease_x < ((callnum->button[k]->pos().x()) + (callnum->button[k]->size().width()))))
{
if((mouseRelease_y > (callnum->button[k]->pos().y())) && (mouseRelease_y < ((callnum->button[k]->pos().y()) + (callnum->button[k]->size().height()))))
{
for(int j=0;jtext(0) == callnum->button[k]->func_name)
{
ui->treeWidget->setCurrentItem(item_level3[j]);
}
}
if(CurWindow.CurSelectWindow == k)
return true;
for(int s=0;s<16;s++)
{
if(video_pos[s] == k)
currrnt_pos = s;
if(video_pos[s] == CurWindow.CurSelectWindow)
last_pos = s;
}
video_pos[last_pos] = k;
video_pos[currrnt_pos] = CurWindow.CurSelectWindow;
CurSelectWindowchange(last_pos);
return true;
}
}
}
return true;
}
}

上面的例子就是一个子窗口的事件过滤器,在事件过滤器中获取鼠标点击的位置

如果事件过滤器中的事件正好是我们想要捕获的就返回true,这样事件就不会转发了,如果事件不是我们想要的,一定要返回false,否则影响其他组件,比如我们这里想要tableWidget_2和btn_record的事件,如果不返回false,每次不管哪个组件进入事件,后续都没法处理,因为事件没有了转发,其他组件无法处理事件了

eventFilter() 函数是 QObject的一个成员函数,因此,任意 QObject 都可以作为事件过滤器(问题在于,如果你没有重写eventFilter() 函数,这个事件过滤器是没有任何作用的,因为默认什么都不会过滤)。已经存在的过滤器则可以通过 QObject::removeEventFilter() 函数移除。

事件过滤器和被安装过滤器的组件必须在同一线程,否则,过滤器将不起作用。

注意,如果你在事件过滤器中 delete 了某个接收组件,务必将函数返回值设为 true。否则,Qt 还是会将事件分发给这个接收组件,从而导致程序崩溃。

只要组件注册了事件过滤器,无论任何操作都会首先进入事件过滤器,就看最后返回的true还是false,返回true不做其他处理,返回false做其他处理。

【领QT开发教程学习资料,点击下方链接莬费领取↓↓,先码住不迷路~】

点击这里:「链接」

展开阅读全文

页面更新:2024-05-30

标签:行号   过滤器   事件   按键   函数   组件   类型   操作   链接   文件

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号

Top