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