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