Qt:让父母决定孩子是否接受事件

时间:2016-08-04 20:28:07

标签: c++ qt

我在尝试获取父对象来过滤子事件时遇到问题。

在以下示例中,我在旋转框上设置了一个事件过滤器。事件过滤器检测旋转框上的鼠标按下事件。然后,我希望父对象根据某些条件接受或忽略该事件。

问题是它似乎接受鼠标按下事件然后忽略鼠标释放事件。这是鼠标滚轮事件的问题。

如何让我的父母接受/忽略该事件?

在实际情况中,消息必须通过更多层传递,但行为是相同的。如果单击旋转框上的向上箭头,将弹出消息,然后数字将开始旋转。

Qt版本:5.6.1

#include "mainwindow.h"

#include <QEvent>
#include <QSpinBox>
#include <QHBoxLayout>
#include <QMessageBox>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    QSpinBox* spinner = new QSpinBox;
    QHBoxLayout* layout = new QHBoxLayout;
    QWidget* widget = new QWidget;
    layout->addWidget(spinner);
    spinner->installEventFilter(this);
    connect(this, SIGNAL(mouse_pressed(QEvent*)),
            this, SLOT(handle_event(QEvent*)));
    widget->setLayout(layout);
    setCentralWidget(widget);
}

MainWindow::~MainWindow()
{

}

bool MainWindow::eventFilter(QObject *watched, QEvent *event)
{
    if (event->type() == QEvent::MouseButtonPress
        event->type() == QEvent::Wheel)
    {
        emit mouse_pressed(event);
    }
    return QMainWindow::eventFilter(watched, event);
}

void MainWindow::handle_event(QEvent* event)
{
    event->ignore();
    QMessageBox(QMessageBox::Warning, "warning", "ignoring event").exec();    
}

编辑1:我找到了部分停止事件级联的方法。在MainWindow :: handle_event(...)中,我调用&#39; event-&gt; setAccepted(false)&#39;,而不是调用&#39; event-&gt; ignore()&#39;,然后检查&#39; event-&gt; isAccepted()&#39;在eventFilter中。如果不被接受,我会忽略该事件。

此解决方案适用于QLineEdit,但QSpinBox和QPushbutton仍无法正常工作。对于QSpinBox,轮子事件仍会更改值,单击旋转按钮会导致持续旋转(未检测到鼠标释放)。对于QPushButton,该事件被忽略但按钮仍处于按下状态。

编辑2:忽略事件后返回false会阻止级联。谢谢@ G.M。提示!我会发一个答案。

1 个答案:

答案 0 :(得分:0)

让父母决定孩子是否应该处理事件的方法是调用'event-&gt; setAccepted(false)',检查eventFilter函数。如果为false,则忽略该事件并从函数返回true。

从eventFilter函数返回true对我来说是违反直觉的,但它正好在文档中。事件过滤器的侵入性远低于子类,因此我很高兴找到解决方案。

#include "mainwindow.h"

#include <QEvent>
#include <QSpinBox>
#include <QHBoxLayout>
#include <QMessageBox>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    QSpinBox* spinner = new QSpinBox;
    QHBoxLayout* layout = new QHBoxLayout;
    QWidget* widget = new QWidget;
    layout->addWidget(spinner);
    spinner->installEventFilter(this);
    connect(this, SIGNAL(mouse_pressed(QEvent*)),
            this, SLOT(handle_event(QEvent*)));
    widget->setLayout(layout);
    setCentralWidget(widget);
}

MainWindow::~MainWindow()
{

}

bool MainWindow::eventFilter(QObject *watched, QEvent *event)
{
    if (event->type() == QEvent::MouseButtonPress
        event->type() == QEvent::Wheel)
    {
        emit mouse_pressed(event);
        if (!event->isAccepted())
        {
            event->ignore();
            return true;
        }
    }
    return QMainWindow::eventFilter(watched, event);
}

void MainWindow::handle_event(QEvent* event)
{
    event->setAccepted(false);
    QMessageBox(QMessageBox::Warning, "warning", "ignoring event").exec();    
}