Как перехватить события Qt Quick qml?

Я хотел бы перехватить события Qt Quick, такие как ключевые события, так что я могу обработать их, прежде чем они достигнут текущей цели, такой как текущий сфокусированный предмет, опционально предотвращая распространение события в цепочке событий по умолчанию. Может ли это быть достигнуто путем обработки события в коде QML?

0

Решение

Это может быть достигнуто путем установки фильтр событий в окне верхнего уровня.
Окно верхнего уровня можно найти и получить к нему доступ в любом месте источника QML, сохранив ссылку на ApplicationWindow с QML Singleton (это не совсем тривиально: следуйте этот или другие руководства и сохранить ссылку в 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
}
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]