2016-08-01 11 views
3

Ich habe eine Situation, in der ich einer Anwendung, die hauptsächlich aus einer QtQuick-Benutzeroberfläche besteht, Tastenkürzel hinzufügen muss. Die Version von Qt Quick ist leider an Qt5.3 gebunden und Shortcuts (wie wir sie brauchen) wurden nur in Qt5.5 bzw. Qt5.7 eingeführt.Wie installiert und verwendet man einen in Qt C++ geschriebenen Ereignisfilter in einer QML-Anwendung

Also, als Lösung, schrieb ich einen Ereignisfilter, der ähnlich wie QShortcut funktioniert (QShortcut kann nicht verwendet werden, daher der Ereignisfilter).

Kann jemand dieses Eventfilter in QML installieren und verwenden?

Antwort

4

Eine Möglichkeit wäre, einen Singleton Typ QML zu entlarven:

#include <QtGui> 
#include <QtQml> 

class ShortcutListener : public QObject 
{ 
    Q_OBJECT 

public: 
    ShortcutListener(QObject *parent = nullptr) : 
     QObject(parent) 
    { 
    } 

    Q_INVOKABLE void listenTo(QObject *object) 
    { 
     if (!object) 
      return; 

     object->installEventFilter(this); 
    } 

    bool eventFilter(QObject *object, QEvent *event) override 
    { 
     if (event->type() == QEvent::KeyPress) { 
      QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event); 
      qDebug() << "key" << keyEvent->key() << "pressed on" << object; 
      return true; 
     } 
     return false; 
    } 
}; 

static QObject *shortcutListenerInstance(QQmlEngine *, QJSEngine *engine) 
{ 
    return new ShortcutListener(engine); 
} 

int main(int argc, char *argv[]) 
{ 
    QGuiApplication app(argc, argv); 

    qmlRegisterSingletonType<ShortcutListener>("App", 1, 0, "ShortcutListener", shortcutListenerInstance); 

    QQmlApplicationEngine engine; 
    engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); 

    return app.exec(); 
} 

#include "main.moc" 

main.qml:

import QtQuick 2.5 
import QtQuick.Window 2.2 

import App 1.0 

Window { 
    id: window 
    width: 640 
    height: 480 
    visible: true 

    Component.onCompleted: ShortcutListener.listenTo(window) 
} 

Wenn Sie mehrere verschiedene Zuhörer haben, könnten Sie es auch tun deklarativ durch Zugabe eines object Eigenschaft zu ShortcutListener, dass es einen Ereignisfilter bei der Installation installieren würde.

Weitere Informationen finden Sie unter Integrating QML and C++.

+0

Danke Mitch, das ist eine ziemlich vollständige Antwort! Ich habe kein QtQuick-Fenster, mit dem man arbeiten kann, das Hauptfenster wird von einem QQuickItem gerendert. Das QQuickItem hat Zugriff auf das Fenster über einen Zeiger, vielleicht kann ich das versuchen. – Hitsugaya198

+0

Ich könnte falsch liegen, aber es sollte egal sein, was das Root-Element ist, solange es wichtige Ereignisse bekommt. – Mitch

+0

Sie könnten Recht haben. Nachteil: Wenn das Objekt, auf dem der Ereignisfilter installiert ist, nicht sichtbar ist/keinen Fokus hat, ist ein Aufruf von grabKeyboard() erforderlich, um zu erzwingen, dass die Eingabetrigger durch dieses Objekt geleitet werden. Dies ist nicht etwas, was ich tun möchte, da es andere QAction-Elemente gibt, deren Verknüpfungen außerhalb meines Ereignisfilters konfiguriert sind. – Hitsugaya198