如何拦截 Qt Quick qml 事件?
Posted
技术标签:
【中文标题】如何拦截 Qt Quick qml 事件?【英文标题】:How to intercept Qt Quick qml events? 【发布时间】:2017-06-17 13:33:47 【问题描述】:我想拦截 Qt Quick 事件,例如 key events,以便我可以在它们到达当前目标(例如当前 focused item)之前对其进行处理,可选择阻止事件在默认事件链中传播。这可以通过在QML代码中处理事件来实现吗?
【问题讨论】:
【参考方案1】:这可以通过在顶层窗口中安装event filter 来实现。
通过使用 QML Singleton 保存对 ApplicationWindow
的引用,可以在 QML 源代码中的任何地方找到和访问***窗口(这并非微不足道:遵循 this 或其他指南并将引用保存在 Component.onCompleted
事件中ApplicationWindow
)。事件过滤器可以通过 C++ QML 注册插件安装。
c++事件过滤插件是这样的:
#pragma once
#include <QQuickItem>
class QmlEventFilter : public QQuickItem
Q_OBJECT
public:
Q_PROPERTY(QObject * source READ getSource WRITE setSource)
Q_PROPERTY(bool filterEnabled READ getFilterEnabled WRITE setFilterEnabled)
public:
QmlEventFilter()
m_source = nullptr;
m_filterEnabled = false;
~QmlEventFilter()
if (m_source != nullptr)
m_source->removeEventFilter(this);
void setSource(QObject *source)
source->installEventFilter(this);
m_source = source;
;
QObject * getSource() return m_source;
void setFilterEnabled(bool value) m_filterEnabled = value;
bool getFilterEnabled() return m_filterEnabled;
private:
void keyPressEvent(QKeyEvent *event) override
// This is actually called when the QML event handler hasn't accepted the event
m_qmlAccepted = false;
// Ensure the event won't be propagated further
event->setAccepted(true);
void keyReleaseEvent(QKeyEvent *event) override
// This is actually called when the QML event handler hasn't accepted the event
m_qmlAccepted = false;
// Ensure the event won't be propagated further
event->setAccepted(true);
bool eventFilter(QObject *obj, QEvent *event) override
if (!m_filterEnabled)
return false;
bool ret = false;
switch (event->type())
case QEvent::KeyPress:
case QEvent::KeyRelease:
m_qmlAccepted = true;
QCoreApplication::sendEvent(this, event);
ret = m_qmlAccepted;
break;
return ret;
private:
QObject *m_source;
bool m_filterEnabled;
bool m_qmlAccepted;
;
它必须像这样在 Qt Quick 应用程序之前注册:
qmlRegisterType<QmlEventFilter>("MyPlugins", 1, 0, "EventFilter");
然后它可以像这样在 QML 源中使用:
import MyPlugins 1.0
[...]
EventFilter
id: filter
filterEnabled: true // It can also be enabled on demand in other events
Keys.onPressed:
// Accepting the event won't propagate the event
// with the default event chain
event.accepted = true
console.log("onPressed")
Component.onCompleted:
// Singleton.window is the top level QML ApplicationWindow
filter.source = Singleton.window
【讨论】:
以上是关于如何拦截 Qt Quick qml 事件?的主要内容,如果未能解决你的问题,请参考以下文章
如何使 Qt Quick (QML) ListView 项目无法选择?
Qt Quick - 如何仅通过 c++ 代码与 qml 属性交互