2012-08-30 11 views
8

Sono in profondità nella creazione di un'applicazione desktop con QML e Qt Creator e attualmente sto ricercando la gestione della tastiera e il modo in cui funziona con gli elementi QML. Sono già a conoscenza della mancanza di appropriate sostituzioni QML per i widget del desktop.Assegnazione di scorciatoie da tastiera a componenti QML

Il mio problema attuale è che desidero assegnare alcune scorciatoie da tastiera globali ad alcuni particolari componenti QML (come l'assegnazione di scorciatoie da tastiera ai pulsanti sulla GUI) che dovrebbero attivarli. Il meglio che ho potuto gestire è usare FocusScope e Key Navigation per essere in grado di navigare la GUI attraverso le tastiere, ma non è la stessa cosa.

Qualcuno può suggerire cosa fare in questo scenario? C'è qualche funzione in arrivo con Qt 5? Non sono riuscito a trovare alcuna informazione su questo su Internet.

+0

Prova questo QShortcut http://doc.qt.nokia.com/4.7-snapshot/qshortcut.html – RajaRaviVarma

+1

QShortCut funziona con le classi basate su QWidget. Non esiste un modo diretto per far sì che gli elementi QML nativi rispondano a scorciatoie globali. Ad esempio, è possibile assegnare una chiave a un pulsante QML, ma funziona solo quando il pulsante è attivo. –

+2

[Le scorciatoie dell'applicazione che utilizzano QShortcut in QML] (http://kdeblog.mageprojects.com/2012/11/28/application-wide-shortcuts-using-qshortcut-in-qml/) sono qualcosa di interessante sulle stesse linee. Sto usando un QDeclarativeView (basato su QWidget) per la schermata principale della GUI con QML incorporato all'interno, quindi una scorciatoia per le applicazioni è ora facile. –

risposta

8

Rispondere alla mia stessa domanda come le scorciatoie sono ora possibili da implementare in Qt 5.1.1. I collegamenti possono essere facilmente associati ai controlli QtQuick come Button, ToolButtons e MenuItem utilizzando l'elemento QML Action. per esempio. :

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" 
    } 
} 

Premendo Ctrl + O si eseguirà l'azione specificata nella sezione onTriggered.

Fare riferimento alla Qt Quick Controls Gallery example

0

Quindi supponendo che si sta chiamando una funzione su quel evento click del pulsante come questo,

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

Quindi è possibile assegnare assegnare tasti di scelta rapida a livello mondiale in questo modo. Ma la limitazione è l'elemento QML globale (un elemento genitore che contiene tutti gli altri elementi QML) dovrebbe avere l'attenzione. Ex. :

Questo non è esattamente quello che vuoi, ma può essere d'aiuto.

+0

Si prega di prestare attenzione al motivo della riduzione dei voti. – RajaRaviVarma

4

È del tutto possibile utilizzare scorciatoia in QML utilizzando EventFilter in C++ (Qt).

Si può fare per i passaggi qui sotto:

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, funziona davvero – Zeks

0

A partire da Qt 5.9 il comportamento desiderato è ancora included:

import QtQuick 2.9 

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

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

Se si omette il contesto, funzionerà solo per le finestre attive, in caso contrario per l'intera applicazione, vedere documentation.

Problemi correlati