2015-08-25 2 views
0

Je peux obtenir des valeurs de clé à partir de HAL via une fonction de rappel dans Qt. événement créé pour cette clé parComment synthétiser les événements de presse de touche?

QKeyEvent *event = new QKeyEvent (QEvent::KeyPress, 
            inputKey.keyValue, 
            Qt::NoModifier); 

Note: inputKey.keyValue valeur clé reçue de la couche HAL.

Maintenant je dois enregistrer cet événement clé dans Qt, donc que si une pression de touche est passé dans IR à distance puis sous forme respective, keyPressEvent(e) ou event(e) va obtenir invoquer. et en fonction de la touche, une action spécifique sera exécutée.

Note: Plus d'une forme est là, où l'événement de pression de touche déclenchera et plus d'un clés sont là « PAGE_UP, Page_Bas, Ok etc ..... clé »

essayé d'invoquer postEvent() et connectez-vous (.......) mais rien ne m'a aidé. KeyPressEvent() n'est pas exécuté.

+1

Vous pouvez lire dans [ce chapitre] (http://doc.qt.io/qt-5/eventsandfilters.html) de la documentation à ce propos. – Bowdzone

+0

Bienvenue sur Stackoverflow. Avez-vous lu sur 'QCoreApplication :: sendEvent()' et 'QCoreApplication :: postEvent()' avant de demander? Avez-vous fait face à des problèmes? Essayez d'ajouter plus de détails à ce sujet. – Ilya

Répondre

1

E.g. comme ceci:

// receiver is a pointer to QObject 
QCoreApplication::postEvent (receiver, event); 

Vous pouvez trouver plus d'informations here.

Vous pouvez réimplémenter QObject::event() ou QWidget::keyPressEvent dans votre widget pour recevoir des événements clés. Visitez ce link ou link pour plus d'informations. Voir l'exemple de code ci-dessous qui se compose de deux boutons et une étiquette. En cliquant sur pushButton envoie 'entrée pressé' et pushButton_2 envoie 'lettre A enfoncé'. Les événements clés sont reçus dans la fonction event() et l'étiquette est mise à jour en conséquence.

MainWindow::MainWindow(QWidget *parent) : 
    QMainWindow(parent), 
    ui(new Ui::MainWindow) 
{ 
    ui->setupUi(this); 
    connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(sendKeyEvent())); 
    connect(ui->pushButton_2, SIGNAL(clicked()), this, SLOT(sendKeyEvent())); 
} 

void MainWindow::sendKeyEvent() 
{ 
    QObject* button = QObject::sender(); 
    if (button == ui->pushButton) 
    { 
     QKeyEvent *event = new QKeyEvent (QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier); 
     QCoreApplication::postEvent (this, event); 
    } 
    else if (button == ui->pushButton_2) 
    { 
     QKeyEvent *event = new QKeyEvent (QEvent::KeyPress, Qt::Key_A, Qt::NoModifier); 
     QCoreApplication::postEvent (this, event); 
    } 
} 

bool MainWindow::event(QEvent *event) 
{ 
    if (event->type() == QEvent::KeyPress) 
    { 
     QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event); 
     if (keyEvent->key() == Qt::Key_Enter) { 
      ui->label->setText("Enter received"); 
      return true; 
     } 
     else if (keyEvent->key() == Qt::Key_A) 
     { 
      ui->label->setText("A received"); 
      return true; 
     } 
    } 

    return QWidget::event(event); 
} 
+0

Mise à jour de la réponse pour inclure un exemple de réception d'un événement clé. – talamaki

+0

Comment envoyer un événement à plusieurs destinataires? – Lalatendu

+0

Vous devez probablement utiliser [eventFilter] (http://doc.qt.io/qt-5/eventsandfilters.html#event-filters). S'il vous plaît, ouvrez une nouvelle question si nécessaire. – talamaki

0

Vous pouvez créer l'événement sur la pile. Utilisez ensuite QCoreApplication::sendEvent avoir l'événement immédiatement livré:

QWidget w1, w2; 
QKeyEvent event(QEvent::KeyPress, inputKey.keyValue, Qt::NoModifier); 
QApplication::sendEvent(&w1, &ev); 
QApplication::sendEvent(&w2, &ev); 

Chaque sendEvent appellera méthode event du widget, qui sera ensuite invoquer les méthodes xxxxEvent protégées selon le cas. Mais ne le faites pas vous-même, car vous contournez les filtres d'événements globaux de l'application et dépendez des détails de l'implémentation.

// WRONG! 
w1.event(&ev); 
// WRONG and won't compile since keyPressEvent is protected 
w2.keyPressEvent(&ev); 

Ou, vous pouvez le créer sur le tas. Qt gère la durée de vie de l'événement dès que vous l'affichez. Après votre publication, l'événement ne vous appartient plus et vous ne pouvez plus le réutiliser. Vous devez créer plusieurs événements pour chaque publication. Le moyen le plus simple d'éviter la répétition est de créer une fonction locale qui produit les événements à la demande.

QWidget w1, w2; 
auto ev = [=]{ return new QKeyEvent(QEvent::KeyPress, inputKey.keyValue, Qt::NoModifier); }; 
QApplication::postEvent(&w1, ev()); 
QApplication::postEvent(&w2, ev()); 

Les événements seront ajoutés à la file d'attente d'événements du thread principal. Une fois que le contrôle retourne à QApplication::exec, ils seront livrés aux widgets un par un. La méthode event des widgets sera appelée depuis QApplication::exec, et non depuis postEvent. L'implémentation QWidget::event décode les types d'événement et appelle les gestionnaires d'accès protégés, tels que keyPressEvent, enterEvent, etc.Sa mise en œuvre suit le schéma suivant:

bool QWidget::event(QEvent * ev) { 
    switch (ev->type()) { 
    case QEvent::KeyPress: 
    keyPressEvent(static_cast<QKeyEvent*>(ev)); 
    return true; 
    case QEvent::Enter: 
    enterEvent(static_cast<QEnterEvent*>(ev)); 
    return true; 
    ... 
    } 
    return QObject::event(ev); 
} 

Lors de l'implémentation des gestionnaires pour les types d'événements qui ont de telles méthodes virtuelles xxxxEvent de commodité, vous devez réimplémenter la méthode virtuelle, et non le event() lui-même. Ainsi votre MainWindow devrait réimplémentez keyPressEvent:

void MainWindow::keyPressEvent(QKeyEvent * event) { 
    if (event->key() == Qt::Key_Enter) 
    ui->label->setText("Enter received"); 
    else if (event->key() == Qt::Key_A) 
    ui->label->setText("A received"); 
    QMainWindow::keyPressEvent(event); 
} 

Si vous souhaitez que vos événements clés à livrer à votre fenêtre immédiatement, et qui semble être une approche raisonnable, votre méthode sendKeyEvent devient beaucoup plus simple:

void MainWindow::sendKeyEvent() 
{ 
    if (sender() == ui->pushButton) { 
    QKeyEvent event(QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier); 
    QApplication::sendEvent(this, &event); 
    } 
    else if (sender() == ui->pushButton_2) { 
    QKeyEvent event(QEvent::KeyPress, Qt::Key_A, Qt::NoModifier); 
    QApplication::sendEvent(this, &event); 
    } 
} 

Cependant, il existe un moyen de simplifier les choses. Rappelons que le QObject prend en charge les propriétés dynamiques. Vous pouvez ainsi assigner facilement les touches comme une propriété des boutons, et d'envoyer automatiquement l'événement à chaque fois qu'un bouton avec une propriété touche a été pressée:

static const char keyPropKey[] = "key"; 

MainWindow::MainWindow(QWidget *parent) : 
    QMainWindow(parent), 
    ui(new Ui::MainWindow) 
{ 
    ui->setupUi(this); 
    connect(ui->pushButton, &QPushButton::clicked, this, &MainWindow::sendKeyEvent); 
    connect(ui->pushButton_2, &QPushButton::clicked, this, &MainWindow::sendKeyEvent); 
    ui->pushButton.setProperty(keyPropKey, (int)Qt::Key_Enter); 
    ui->pushButton.setProperty(keyPropKey, (int)Qt::Key_A); 
} 

void MainWindow::sendKeyEvent() 
{ 
    auto key = sender().property(KeyPropKey); 
    if (key.isValid()) { 
    QKeyEvent event(QEvent::KeyPress, key.toInt(), Qt::NoModifier); 
    QApplication::sendEvent(this, &event); 
    } 
} 

Enfin, comme nitpick stylistique: il n'y a aucune raison d'avoir la ui membre être un pointeur. Vous éviterez une allocation de tas, et beaucoup d'indirections, en l'utilisant comme membre direct.