2012-08-30 18 views
8

Jestem głęboko zaangażowany w tworzenie aplikacji komputerowych z QML i Qt Creator, a ja obecnie badam obsługę klawiatury i jej działanie z elementami QML. Jestem już świadomy braku prawidłowych zamienników QML dla Desktop Widgets.Przypisywanie skrótów klawiaturowych komponentom QML

Mój obecny problem polega na tym, że chcę przypisać niektóre globalne skróty klawiaturowe do niektórych konkretnych komponentów QML (np. Przypisywanie skrótów klawiaturowych do przycisków w interfejsie GUI), które powinny je aktywować. Najlepsze, co mogę zrobić, to używać FocusScopes i Key Navigation, aby móc nawigować po GUI za pomocą klawiatury, ale to nie jest to samo.

Czy ktoś może sugerować, co zrobić w tym scenariuszu? Czy Qt 5 zawiera taką funkcję? Nie mogłem znaleźć żadnych informacji na ten temat w Internecie.

+0

Wypróbuj ten QShortcut http://doc.qt.nokia.com/4.7-snapshot/qshortcut.html – RajaRaviVarma

+1

QShortCut działa z klasami opartymi na QWidget. Nie ma bezpośredniego sposobu, aby rodzime elementy QML reagowały na globalne skróty. Można na przykład przypisać klawisz do przycisku QML, ale działa on tylko wtedy, gdy przycisk jest ostry. –

+2

[Szerokie zastosowanie skrótów przy użyciu QShortcut w QML] (http://kdeblog.mageprojects.com/2012/11/28/application-wide-shortcuts-using-qshortcut-in-qml/) jest czymś interesującym na tych samych liniach. Korzystam z QDeclarativeView (oparty na QWidget) dla głównego ekranu GUI z wbudowanym QML, więc skrót do aplikacji jest teraz łatwy. –

Odpowiedz

8

Odpowiedzi na moje własne pytanie jako skróty można teraz zaimplementować w Qt 5.1.1. Skróty można z łatwością łączyć z elementami sterującymi QtQuick, takimi jak Button, ToolButtons i MenuItem, używając elementu QML Action. na przykład :

ApplicationWindow { 
    ... 
    ToolButton { action: openAction } // Add a tool button in a ToolBar 
    ... 
    Action { 
     id: openAction 
     text: "&Open" 
     shortcut: "Ctrl+O" 
     onTriggered: // Do some action 
     tooltip: "Open an image" 
    } 
} 

Naciśnięcie Ctrl + O wykona akcję określoną w sekcji "Włączony".

Patrz Qt Quick Controls Gallery example

0

Więc zakładając, że wywołanie funkcji na tym przycisku kliknij zdarzenie jak to,

Button { 
    ... 
    MouseArea { 
    anchor.fill: parent 
    onClicked: callThisFunction(); 
    } 
} 

Następnie można przypisać przypisać globalne skróty klawiszowe w ten sposób. Ograniczeniem jest jednak skupienie się na globalnym elemencie QML (element macierzysty, który zawiera wszystkie inne elementy QML). Dawny. :

Rectangle { 
    id: parentWindow 
    ... 
    ... 
    Button { 
    ... 
    MouseArea { 
     anchor.fill: parent 
     onClicked: callThisFunction(); 
    } 
    } 
    Keys.onSelectPressed: callThisFunction() 
} 

To nie jest dokładnie to, czego potrzebujesz, ale może pomóc.

+0

Proszę podać przyczynę odrzucenia głosów. – RajaRaviVarma

4

można całkowicie używać skrótu w QML za pomocą EventFilter w C++ (Qt).

Można to zrobić poprzez poniżej kroki:

1. Create a Shortcut class by C++. 
2. Register QML Type for Shortcut class 
3. Import Shortcut to QML file and handle it. 

#ifndef SHORTCUT_H 
 
#define SHORTCUT_H 
 

 
#include <QDeclarativeItem> 
 

 
class Shortcut : public QObject 
 
{ 
 
    Q_OBJECT 
 
    Q_PROPERTY(QVariant key READ key WRITE setKey NOTIFY keyChanged) 
 
public: 
 
    explicit Shortcut(QObject *parent = 0); 
 

 
    void setKey(QVariant key); 
 
    QVariant key() { return m_keySequence; } 
 

 
    bool eventFilter(QObject *obj, QEvent *e); 
 

 
signals: 
 
    void keyChanged(); 
 
    void activated(); 
 
    void pressedAndHold(); 
 

 
public slots: 
 

 
private: 
 
    QKeySequence m_keySequence; 
 
    bool m_keypressAlreadySend; 
 
}; 
 

 
#endif // SHORTCUT_H

#include "shortcut.h" 
 
#include <QKeyEvent> 
 
#include <QCoreApplication> 
 
#include <QDebug> 
 
#include <QLineEdit> 
 
#include <QGraphicsScene> 
 

 
Shortcut::Shortcut(QObject *parent) 
 
    : QObject(parent) 
 
    , m_keySequence() 
 
    , m_keypressAlreadySend(false) 
 
{ 
 
    qApp->installEventFilter(this); 
 
} 
 

 
void Shortcut::setKey(QVariant key) 
 
{ 
 
    QKeySequence newKey = key.value<QKeySequence>(); 
 
    if(m_keySequence != newKey) { 
 
     m_keySequence = key.value<QKeySequence>(); 
 
     emit keyChanged(); 
 
    } 
 
} 
 

 
bool Shortcut::eventFilter(QObject *obj, QEvent *e) 
 
{ 
 
    if(e->type() == QEvent::KeyPress && !m_keySequence.isEmpty()) { 
 
//If you want some Key event was not filtered, add conditions to here 
 
     if ((dynamic_cast<QGraphicsScene*>(obj)) || (obj->objectName() == "blockShortcut") || (dynamic_cast<QLineEdit*>(obj))){ 
 
      return QObject::eventFilter(obj, e); 
 
     } 
 
     QKeyEvent *keyEvent = static_cast<QKeyEvent*>(e); 
 

 
     // Just mod keys is not enough for a shortcut, block them just by returning. 
 
     if (keyEvent->key() >= Qt::Key_Shift && keyEvent->key() <= Qt::Key_Alt) { 
 
      return QObject::eventFilter(obj, e); 
 
     } 
 

 
     int keyInt = keyEvent->modifiers() + keyEvent->key(); 
 

 
     if(!m_keypressAlreadySend && QKeySequence(keyInt) == m_keySequence) { 
 
      m_keypressAlreadySend = true; 
 
      emit activated(); 
 
     } 
 
    } 
 
    else if(e->type() == QEvent::KeyRelease) { 
 
     m_keypressAlreadySend = false; 
 
    } 
 
    return QObject::eventFilter(obj, e); 
 
}

qmlRegisterType<Shortcut>("Project", 0, 1, "Shortcut");

import Project 0.1 
 

 
Rectangle { 
 
................. 
 
................. 
 
Shortcut { 
 
     key: "Ctrl+C" 
 
     onActivated: { 
 
      container.clicked() 
 
      console.log("JS: " + key + " pressed.") 
 
     } 
 
    } 
 

 
}

+0

Thx, to naprawdę działa – Zeks

0

Począwszy od Qt 5.9 pożądane zachowanie jest nawet included:

import QtQuick 2.9 

Item { 
    Shortcut { 
     context: Qt.ApplicationShortcut 
     sequences: [StandardKey.Close, "Ctrl+W"] 

     onActivated: { 
      container.clicked() 
      console.log("JS: Shortcut activated.") 
     } 
    } 
} 

Jeśli pominąć kontekst, to będzie działać tylko dla aktualnie aktywnego okna, w przeciwnym razie dla całej aplikacji, zobacz documentation.

Powiązane problemy