[C++ : Qt]Simuler appuie touche clavier

little_programmeur Messages postés 54 Date d'inscription   Statut Membre Dernière intervention   -  
 JazzJackrabbit -
Bonjour,
je souhaiterai pouvoir faire un mini clavier affiché sur l'écran en C++ : lorsque l'on clique sur le bouton 'A', cela simule un véritable appuie sur une touche. J'aimerai bien le faire avec Qt ou l'extension Qxt pour que mon programme soit compatible linux.

Savez vous comment simuler l'appuie d'une touche clavier via QT ?

Merci d'avance.

16 réponses

loupius Messages postés 697 Date d'inscription   Statut Membre Dernière intervention   148
 
Par exemple pour envoyer la touche 'Tab':
  QKeyEvent event(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier);
  QApplication::sendEvent(this, &event);
Bonne continuation.
2
loupius Messages postés 697 Date d'inscription   Statut Membre Dernière intervention   148
 
Ah tu veux envoyer une touche à une autre application !
Alors il te faut choisir un autre mode de communication, par exemple D-Bus; tu as de la chance, ce mode est implémenté dans Qt.
Voir la doc.
2
Char Snipeur Messages postés 9813 Date d'inscription   Statut Contributeur Dernière intervention   1 299
 
ça dépend de qui tu veux qui récupère le signal TAB.
Là c'est l'application, mais il faut savoir ce qu'elle doit en faire de ce signal TAB.
1
loupius Messages postés 697 Date d'inscription   Statut Membre Dernière intervention   148
 
Salut petit programmeur ;-)
Et qu'est-ce qui te dit que la touche n'est pas envoyée... à 'this', c'est-à-dire, dans ton cas, à un objet 'MainWindow' et c'est-à-dire à l'objet qui veut simuler une touche. Pour le recevoir, il faut redéfinir une fonction 'keyPressEvent'.
En général, on ne s'envoie pas une touche, on l'envoie à un autre objet.
Bonne continuation.
1

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
little_programmeur Messages postés 54 Date d'inscription   Statut Membre Dernière intervention   4
 
Et justement : comment choisir l'application à qui envoyer la touche si on veux que ça soit l'application au premier plan, le bureau etc ? J'ai essayé :

void MainWindow::performGlobalShortcutA()
{
QKeyEvent event(QEvent::KeyPress, Qt::Key_A, Qt::NoModifier);
QApplication::sendEvent(QApplication::desktop() , &event);
qDebug() << "test" ;

}


Mais rien de plus...
1
little_programmeur Messages postés 54 Date d'inscription   Statut Membre Dernière intervention   4
 
Je ne comprend pas comment fonctionne D-Bus. Pourriez vous m'expliquer SVP ? Ca fonctionne seulement pour linux ou j'ai mal compris ?
1
little_programmeur Messages postés 54 Date d'inscription   Statut Membre Dernière intervention   4
 
J'ai essayé de faire ce que tu disait mais j'ai une erreur :
mainwindow.cpp:26: error: variable ‘QKeyEvent event’ has initializer but incomplete type
mainwindow.cpp:26: error: incomplete type ‘QEvent’ used in nested name specifier
mainwindow.cpp:27: error: incomplete type ‘QApplication’ used in nested name specifier


Où est l'erreur ?
0
loupius Messages postés 697 Date d'inscription   Statut Membre Dernière intervention   148
 
J'ai extrait ces deux lignes d'un de mes programmes. Le récepteur 'this' n'est qu'un exemple, il faut adapter selon le récepteur désiré.
L'exemple donné dans la doc de Qt est:
  QMouseEvent event(QEvent::MouseButtonPress, pos, 0, 0, 0);
  QApplication::sendEvent(mainWindow, &event);
Bonne réflexion.
0
little_programmeur Messages postés 54 Date d'inscription   Statut Membre Dernière intervention   4
 
Je ne comprend pas... J'ai essayé plusieurs types de code est toujours cette erreur...
voici mon code :
// main.cpp
#include "MaFenetre.h"
#include <Qxt/QxtGui/QxtApplication>
#include <QWidget>

int main(int argc, char *argv[])
{
QxtApplication a(argc, argv);
MaFenetre w;
w.show();
return a.exec();
}

+++++++++
//MaFenetre.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QWidget>
#include <QtGui/QMainWindow>
#include <QPushButton>
#include <QDebug>
#include <QApplication>
#include <QKeyEvent>
#include <Qxt/QxtGui/QxtGlobalShortcut>

class MaFenetre : public QWidget
{
Q_OBJECT

public:
MaFenetre();
~MaFenetre();

private:
QxtGlobalShortcut * shortcutA;


private slots:
void performGlobalShortcutA();



};

#endif // MAINWINDOW_H

+++++++++
//MaFenetre.cpp
#include "mainwindow.h"
#include <iostream>
#include <QCursor>

using namespace std;

MainWindow::MainWindow() : QWidget ()
{
QPushButton * btn = new QPushButton("close",this);
QObject::connect(btn, SIGNAL(clicked()), this, SLOT(close()));

shortcutA= new QxtGlobalShortcut(this);
shortcutA->setShortcut(QKeySequence("F1"));
QObject::connect(shortcutA, SIGNAL(activated()), this, SLOT(performGlobalShortcutA()));

}

MainWindow::~MainWindow()
{

}
void MainWindow::performGlobalShortcutA()
{
// qDebug() << "a";
//QCursor::setPos(0, 0);
QWidget * wf = QApplication::focusWidget();

QKeyEvent event(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier);
QApplication::sendEvent(wf, &event);

}

Et l'erreur :
mainwindow.cpp: In member function ‘void MainWindow::performGlobalShortcutA()’:
mainwindow.cpp:26: error: incomplete type ‘QApplication’ used in nested name specifier
mainwindow.cpp:28: error: variable ‘QKeyEvent event’ has initializer but incomplete type
mainwindow.cpp:28: error: incomplete type ‘QEvent’ used in nested name specifier
mainwindow.cpp:29: error: incomplete type ‘QApplication’ used in nested name specifier


Voyez vous pourquoi mon code plante ??? Je n'y comprend plus rien...

Merci d'avance
0
Char Snipeur Messages postés 9813 Date d'inscription   Statut Contributeur Dernière intervention   1 299
 
normalement, dans QWidget il y a des fonctions qu'il suffit de surcharger pour traiter les évènements du clavier.
0
little_programmeur Messages postés 54 Date d'inscription   Statut Membre Dernière intervention   4
 
Je suis allé voir dans QWidget et j'ai trouvé quelques méthodes relatives au clavier mais je les comprend pas... Elles ne prennent aucun paramètre, et ne renvoie rien. A quoi servent elles ? http://doc.trolltech.com/4.3/qwidget.html#grabKeyboard http://doc.trolltech.com/4.3/qwidget.html#releaseKeyboard
0
Char Snipeur Messages postés 9813 Date d'inscription   Statut Contributeur Dernière intervention   1 299
 
Je pensais plutôt à ça : http://doc.trolltech.com/4.3/qwidget.html#keyPressEvent
0
little_programmeur Messages postés 54 Date d'inscription   Statut Membre Dernière intervention   4
 
Non, ca ne fonctionne pas. Cette fonction sert juste à vérifier si l'utilisateur à appuyé sur une touche, et si oui laquelle, mais on ne peux pas simuler l'appuie de touche...
0
Char Snipeur Messages postés 9813 Date d'inscription   Statut Contributeur Dernière intervention   1 299
 
Oui, j'ai pris le problème à l'envers.
La solution de loupious me semble bonne. Les erreurs ressemblent à des erreurs d'inclusion.
As tu bien mis <QKeyEvent> dans les fichiers correspondant ?
0
little_programmeur Messages postés 54 Date d'inscription   Statut Membre Dernière intervention   4
 
Pour l'erreur decompilation, c'était bien un problème d'inclusion, mais après avoir compilé, le programme ne fonctionne pas. Lorsque j'appuie sur a (la touche qui doit servir de "signal") la touche tab n'est pas simulée. Est-ce parceque la simulation n'est valable que pour la fenêtre actuelle ou est-ce un problème de Qt, de mon programme ou est-ce car je suis sous linux ?

Voila mon .cpp :
#include "mainwindow.h"
#include <iostream>
#include <QCursor>
using namespace std;

MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QPushButton * btn = new QPushButton("close",this);
QObject::connect(btn, SIGNAL(clicked()), this, SLOT(close()));

shortcutA= new QxtGlobalShortcut(this);
shortcutA->setShortcut(QKeySequence("a"));
QObject::connect(shortcutA, SIGNAL(activated()), this, SLOT(performGlobalShortcutA()));


}

MainWindow::~MainWindow()
{

}
void MainWindow::performGlobalShortcutA()
{
QKeyEvent event(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier);
QApplication::sendEvent(this, &event);
qDebug() << "test" ;

}


J'utilise Qxt pour les raccourcis.
0
JazzJackrabbit
 
[[ 5 ans après je sais, mais c'est une information ouverte ]] Si tu souhaite avoir le clavier visuel (externe), exécute le processus osk.exe ^-^ bonne chance.
0