关于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控件消耗的问题。

相关推荐
ShineWinsu11 小时前
对于Qt:QTabWidget常见属性的解析
开发语言·数据库·c++·qt·浏览器·qtabwidget·标签页
慧都产品智能化3 天前
Qt 表格升级攻略:复用已有编辑器,减少重复开发
c++·qt·编辑器·qt6.3
ShineWinsu3 天前
对于Qt:QTableWidget常见属性以及QTableWidgetItem类的解析
开发语言·c++·qt·gui·客户端·表格·qtablewidget
ShineWinsu3 天前
对于Qt:QListWidget常见属性以及QListWidgetItem类的解析
开发语言·c++·qt·客户端·列表·qlistwidget·qlistwidgetitem
ShineWinsu4 天前
对于Qt:QDial常见属性以及信号的解析
开发语言·c++·qt·gui·客户端·旋钮·qdial
宛 禾4 天前
Qt 事件系统完全指南:从事件循环到实战避坑
qt
敲上瘾4 天前
Qt Widgets入门:项目模板解析与Hello World
开发语言·数据库·c++·qt·ui·qt6.3
MOONICK5 天前
QT元数据
开发语言·qt
橙橙笔记5 天前
QT的学习第四部分
linux·qt·学习·音视频
sycmancia6 天前
Qml——信号连接、自定义信号
qt