Qt小部件在光标不在小部件上时检测鼠标事件

3

我创建了一个非常简单的Qt项目,其中包含两个类。其中之一是重新实现的小部件,具有以下方法:

#include "mywidget.h"

// Qt
#include <QMouseEvent>
#include <QMessageBox>

// Debug
#include <QDebug>

MyWidget::MyWidget(QWidget *parent) :
    QWidget(parent)
{
}

void MyWidget::mousePressEvent(QMouseEvent *event)
{
    QMessageBox::information(this, "", "");
}

另一个类是主类,它具有以下方法:
#include "mainwindow.h"

// My headers
#include "mywidget.h"

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
    this->setCentralWidget(new QWidget());

    QWidget *mw = new MyWidget(this->centralWidget());


    // setting backgrounds for visibility
    mw->setPalette( QPalette(Qt::green) );
    mw->setAutoFillBackground(true);

    mw->move(20, 20);
    mw->resize(50, 50);
}

MainWindow::~MainWindow()
{
}

非常简单。在主窗口中只能找到一个小部件。当按下鼠标按钮时,此小部件会创建一个消息框。当消息框出现后,如果我用左键单击“确定”按钮,则一切正常,但是如果我按下“空格键”或“回车键”来激活按钮,则程序会变得疯狂:如果我单击任何地方(无论是在小部件区域内还是外部),绿色小部件都会像我单击了它一样,并弹出消息框。
为什么会这样?我该如何抑制这种行为?

为什么不直接将MyWidget设置为中心窗口部件呢?像这样:QWidget *mw = new MyWidget; setCentralWidget(mw); - vahancho
因为这个小项目只是一个大型项目中已存在问题的一种表达方式,而且问题比这更加复杂。 - Bartis Áron
1个回答

1

当前实现的mousePressEvent会接受鼠标事件,使您的小部件成为鼠标抓取器。但是,突然间您创建了一个新窗口,它夺走了焦点,您的小部件就无法接收到鼠标释放事件,因此它无法释放鼠标抓取。

当您单击消息框时,它会接管鼠标抓取,并且一切都按照预期工作。在其他情况下,您的小部件重新获得焦点,您的小部件仍然控制着鼠标。

我会说这是Qt的错误(在窗口焦点更改时,小部件应该释放鼠标),只有与您的错误代码结合使用时才会出现。

有两个解决方案:

  1. 不要接受鼠标按下事件,在mousePressEvent中添加event->ignore();
  2. 将消息框的创建移动到mouseReleaseEvent中。还需要一个空的mousePressEvent实现。

实际上在我的原始代码中,该事件是双击(在第二次鼠标按下时激活,而不是松开),并打开了一个配置窗口。因此:1.我不能忽略该事件,2.“释放事件”部分也不可能。 - Bartis Áron

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接