2012-08-30 17 views
8

Tengo mucha experiencia en la creación de una aplicación de escritorio con QML y Qt Creator, y actualmente estoy investigando el manejo del teclado y cómo funciona con los elementos QML. Ya soy consciente de la falta de reemplazos de QML adecuados para Widgets de escritorio.Asignación de atajos de teclado a componentes QML

Mi problema actual es que deseo asignar algunos atajos de teclado globales a algunos componentes particulares de QML (como la asignación de atajos de teclado a botones en la GUI) que deberían activarlos. Lo mejor que puedo hacer es usar FocusScopes y Key Navigation para poder navegar por la GUI a través de los teclados, pero esto no es lo mismo.

¿Alguien puede sugerir qué hacer en este escenario? ¿Hay alguna de esas características entrando con Qt 5? No pude encontrar ninguna información sobre esto en Internet.

+0

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

+1

QShortCut funciona con clases basadas en QWidget. No hay una forma directa de hacer que los elementos QML nativos respondan a los atajos globales. Uno puede asignar una tecla a un Botón QML, por ejemplo, pero solo funciona cuando el botón tiene foco. –

+2

[Accesos directos a toda la aplicación usando QShortcut en QML] (http://kdeblog.mageprojects.com/2012/11/28/application-wide-shortcuts-using-qshortcut-in-qml/) es algo interesante en la misma línea. Estoy usando QDeclarativeView (basado en QWidget) para la pantalla principal de la GUI con QML incrustado en el interior, por lo que ahora es fácil usar un atajo de toda la aplicación. –

Respuesta

8

Respondiendo a mi propia pregunta, ya que los accesos directos ahora son posibles de implementar en Qt 5.1.1. Los accesos directos se pueden enlazar fácilmente a los controles QtQuick como Button, ToolButtons y MenuItem utilizando el elemento QML Action. p.ej. :

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

Al pulsar Ctrl + O se ejecutará la acción especificada en la sección onTriggered.

Consulte Qt Quick Controls Gallery example

0

Así que asumiendo que usted está llamando a una función en ese evento de clic de botón como este,

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

A continuación, puede asignar asignar atajos de teclado globales de esta manera. Pero la limitación es que el elemento Global QML (un elemento padre que contiene todos los demás elementos QML) debe tener el foco. Ex. :

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

Esto no es exactamente lo que quiere pero puede ayudar.

+0

Por favor, escriba la razón de los votos a la baja. – RajaRaviVarma

4

Puede utilizar totalmente acceso directo en QML usando EventFilter en C++ (Qt).

Puede hacerlo mediante los pasos siguientes:

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, realmente funciona – Zeks

0

A partir de Qt 5.9 el comportamiento deseado es aún included:

import QtQuick 2.9 

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

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

Si se omite el contexto, sólo funcionará para ventanas activas, de lo contrario para toda la aplicación, consulte documentation.

Cuestiones relacionadas