Qt:让父母决定孩子是不是接受事件
Posted
技术标签:
【中文标题】Qt:让父母决定孩子是不是接受事件【英文标题】:Qt: Have parent decide whether or not a child accepts eventQt:让父母决定孩子是否接受事件 【发布时间】:2016-08-04 20:28:06 【问题描述】:我在尝试让父对象过滤子事件时遇到问题。
在以下示例中,我在旋转框上设置了一个事件过滤器。事件过滤器检测旋转框上的鼠标按下事件。然后,我希望父对象根据某些标准接受或忽略该事件。
问题是它似乎接受了鼠标按下事件,然后忽略了鼠标释放事件。这是鼠标滚轮事件的问题。
我怎样才能让我的父母接受/忽略该事件?
在实际情况下,消息必须通过更多层,但行为是相同的。如果您单击旋转框上的向上箭头,则会弹出消息,然后数字将开始旋转。
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(...) 中,我调用 'event->setAccepted(false)',而不是调用 'event->ignore()',然后在 eventFilter 中检查 'event->isAccepted()' .如果不被接受,我会忽略该事件。
此解决方案在 QLineEdit 上运行良好,但在 QSpinBox 和 QPushbutton 上仍无法正常运行。对于 QSpinBox,滚轮事件仍会更改值,单击旋转按钮会导致持续旋转(未检测到鼠标释放)。对于 QPushButton,该事件被忽略,但按钮保持按下状态。
编辑 2: 忽略事件后返回 false 会阻止级联。谢谢@GM提示!我会发布一个答案。
【问题讨论】:
Qt 根据return value fromeventFilter
决定是否进一步处理事件,但您永远不会从自己的实现中明确返回true
或false
。您还声明“问题是它似乎接受了鼠标按下事件,然后忽略了鼠标释放事件”,但您没有显示任何处理鼠标释放事件的代码。
我在eventFilter中返回继承对象函数的结果。 MouseButtonRelease 事件不会保留其默认行为吗?我在 QPushButtons 上看到了同样的问题(他们一直很沮丧)。即使我处理 MouseButtonRelease 事件并调用 btn->setDown(false)。
【参考方案1】:
让父母决定孩子是否应该处理事件的方法是调用“event->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();
【讨论】:
以上是关于Qt:让父母决定孩子是不是接受事件的主要内容,如果未能解决你的问题,请参考以下文章