2017-06-17 125 views

回答

1

這可以通過在頂層窗口中安裝event filter來實現。 通過使用QML Singleton保存對ApplicationWindow的引用(這不是非常簡單:按照this或其他指南並將參考保存在Component.onCompleted事件ApplicationWindow中),可以在QML源中的任何地方找到並訪問頂層窗口。事件過濾器可以安裝一個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快速應用這樣之前註冊:

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 
}