关于Qt中鼠标左键事件被子控件截留的处理

Qt中,我重写鼠标按下事件虚函数:

void MainWindow::mousePressEvent(QMouseEvent *m)

{

QPoint pt=m->pos();

qDebug()<<pt; //显示坐标

if (m->button()==Qt::LeftButton)

{

qDebug() << "左键被按下";

}

else

{

qDebug() << "右键被按下";

}

}

运行结果:鼠标左键点击无反应,无"坐标值"显示也无"左键被按下"显示,但右键一切正常,问题出在哪里?

"程序运行,左键点击无反应,右键正常",将这一问题问DeepSeek,回答是某个或某些子控件拦截了左键事件。事实如此,因为我在窗口上平铺了一个TextEdit(名字textEdit),鼠标事件被它截留了。

处理方法一:让子控件对鼠标事件"透明"

如果让鼠标事件能够"穿透"textEdit,则上述代码中关于左键的部分会被执行。具体做法是在MainWindow构造函数中作如下设置:

ui->textEdit->setAttribute(Qt::WA_TransparentForMouseEvents, true);

此时,运行程序,"坐标值"、"左键被按下"会显示出来。

处理方法二:安装事件过滤器(Event Filter)

如果不想修改子控件的属性,可以在MainWindow中给textEdit控件安装事件过滤器,在事件到达子控件之前进行拦截,在过滤器函数中处理鼠标左键事件。这里还需要提一句,textEdit截留鼠标左键事件时是通过它的视口(viewport)进行的,因此过滤器不能直接安在textEdit上,而是要安在它的viewport上,做法如下:

//在MainWindow的构造函数中:

ui->textEdit->viewport()->installEventFilter(this);

//然后重写eventFilter函数(记得先在头文件中做声明)

bool MainWindow::eventFilter(QObject *watched, QEvent *event)

{

if (watched == ui->textEdit->viewport() && event->type() ==

QEvent::MouseButtonPress) {

QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);

if (mouseEvent->button() == Qt::LeftButton) {

qDebug() << "左键被按下" << mouseEvent->pos();

// 如果希望事件就此终止,返回 true;如果还想让子控件处理,返回 false

return true;

}

}

return QMainWindow::eventFilter(watched, event); // 传递其他事件

}

至此,通过在TextEdit上安装过滤器,并重写过滤器函数的方法解决了鼠标左键事件被TextEdit控件消耗的问题。

相关推荐
初阳7856 小时前
【基于Qt5仿音乐播放器(一)】——项目准备
qt·1024程序员节
kaixin_learn_qt_ing9 小时前
Qt开发工程师
qt
ShineWinsu1 天前
对于Qt:信号与槽的解析
c++·qt·gui·lambda·信号·信号与槽·槽函数
努力实干1 天前
Qt/C++ 模块化设计与工程组织
开发语言·c++·qt
Lhan.zzZ1 天前
Qt:动态库模块框架设计
开发语言·c++·qt
qq_401700412 天前
TCP 长连接、心跳包与断线自动重连设计:工业级通信的“不死鸟”架构
网络·qt·tcp/ip
dyxal3 天前
A2A 协议 v1.0 完全指南:方法名、Agent Card、三种绑定与 FastAPI 实战
开发语言·qt·fastapi
金色熊族3 天前
在Qt中使用asan检测内存泄漏(一)
linux·qt·asan
前行中的小猪3 天前
Qt 5 踩坑实录:多显示器跨屏拖拽导致窗口异常放大与 setGeometry 报错的深度解析与根治
qt·多显示器·高分辨率·多屏幕