QWidgetWindow 在 Qt5 的事件过滤器中作为 QObject
QWidgetWindow as QObject in event filter with Qt5
在将某些代码从 Qt4 迁移到 Qt5 时,我必须过滤我的应用程序上的事件,但它不再起作用。我的软件必须在 "Edition Mode" 中过滤所有事件,因此只有少数 widgets/buttons 可以是 available/clickable.
我有一个 class InputGrabber
和一个 QVector
指向 QWidget
的指针和一个 eventFilter
函数。当传递到 "Edit" 模式时,我将小部件的指针附加到我的 InputGrabber
的 QVector
上,它将可用:
_inputGrabber->add (_gpView);
_inputGrabber->add (_gpView->viewport ());
_inputGrabber->add (_gpView->horizontalScrollBar ());
_inputGrabber->add (_gpView->verticalScrollBar ());
_inputGrabber->add (_view->mainWindow().toolBarMap()["editSquel"]);
然后,在 eventFilter 函数上,代码如下:
bool InputGrabber::eventFilter (QObject* object, QEvent* anevent)
{
if (QInputEvent* event = dynamic_cast <QInputEvent*> (anevent))
{
QWidget* widget = dynamic_cast <QWidget*> (object);
if (widget)
{
if (_widgetList.contains (widget) || _widgetList.contains (widget->parentWidget ()))
return QObject::eventFilter (object, event);
else if (QDialog* dlg = dynamic_cast <QDialog*> (widget))
return QObject::eventFilter (object, event);
else if (QDialogButtonBox* dlg = dynamic_cast <QDialogButtonBox*> (widget->parentWidget ()))
return QObject::eventFilter (object, event);
else
return true;
}
else
return true;
}
else
return QObject::eventFilter (object, event);
}
}
迁移到 Qt5 的问题是以下转换:
QWidget* widget = dynamic_cast <QWidget*> (object);
returns NULL
当对象继承自 QWidgetWindow
.
有没有人发现同样的问题并得到遵循相同策略的解决方案?我不想更改我的软件的行为,在所有小部件上循环并为每个小部件设置 setDisabled()
。
非常感谢!
我认为你的代码在这里是错误的:
return QObject::eventFilter (object, event);
应该是
return QObject::eventFilter (object, anevent);
并且可能:
bool InputGrabber::eventFilter (QObject* object, QEvent* anevent)
{
if (QInputEvent* event = dynamic_cast <QInputEvent*> (anevent))
{
//etc
}
return QObject::eventFilter (object, anevent);
}
这样,如果您没有明确地 return true 或 false,它将始终正确地传播链中的事件。
如果你的转换失败,就不要return任何东西,让它回到最后一行。如果您在遇到一个您一无所知的对象(例如 misterious QWidgetWindow)时以某种方式停止了事件传播,您可能会破坏 UI 逻辑。如果任由传播下去,很可能你等待的事件迟早会出现。
在将某些代码从 Qt4 迁移到 Qt5 时,我必须过滤我的应用程序上的事件,但它不再起作用。我的软件必须在 "Edition Mode" 中过滤所有事件,因此只有少数 widgets/buttons 可以是 available/clickable.
我有一个 class InputGrabber
和一个 QVector
指向 QWidget
的指针和一个 eventFilter
函数。当传递到 "Edit" 模式时,我将小部件的指针附加到我的 InputGrabber
的 QVector
上,它将可用:
_inputGrabber->add (_gpView);
_inputGrabber->add (_gpView->viewport ());
_inputGrabber->add (_gpView->horizontalScrollBar ());
_inputGrabber->add (_gpView->verticalScrollBar ());
_inputGrabber->add (_view->mainWindow().toolBarMap()["editSquel"]);
然后,在 eventFilter 函数上,代码如下:
bool InputGrabber::eventFilter (QObject* object, QEvent* anevent)
{
if (QInputEvent* event = dynamic_cast <QInputEvent*> (anevent))
{
QWidget* widget = dynamic_cast <QWidget*> (object);
if (widget)
{
if (_widgetList.contains (widget) || _widgetList.contains (widget->parentWidget ()))
return QObject::eventFilter (object, event);
else if (QDialog* dlg = dynamic_cast <QDialog*> (widget))
return QObject::eventFilter (object, event);
else if (QDialogButtonBox* dlg = dynamic_cast <QDialogButtonBox*> (widget->parentWidget ()))
return QObject::eventFilter (object, event);
else
return true;
}
else
return true;
}
else
return QObject::eventFilter (object, event);
}
}
迁移到 Qt5 的问题是以下转换:
QWidget* widget = dynamic_cast <QWidget*> (object);
returns NULL
当对象继承自 QWidgetWindow
.
有没有人发现同样的问题并得到遵循相同策略的解决方案?我不想更改我的软件的行为,在所有小部件上循环并为每个小部件设置 setDisabled()
。
非常感谢!
我认为你的代码在这里是错误的:
return QObject::eventFilter (object, event);
应该是
return QObject::eventFilter (object, anevent);
并且可能:
bool InputGrabber::eventFilter (QObject* object, QEvent* anevent)
{
if (QInputEvent* event = dynamic_cast <QInputEvent*> (anevent))
{
//etc
}
return QObject::eventFilter (object, anevent);
}
这样,如果您没有明确地 return true 或 false,它将始终正确地传播链中的事件。
如果你的转换失败,就不要return任何东西,让它回到最后一行。如果您在遇到一个您一无所知的对象(例如 misterious QWidgetWindow)时以某种方式停止了事件传播,您可能会破坏 UI 逻辑。如果任由传播下去,很可能你等待的事件迟早会出现。