0
0
Envoyer des événements clavier ou souris
Premièrement, les boutons héritent de QPushButton pour ajouter le support du "mouse over" (survol par le curseur), avec la fonction d'auto-répétition liée.
Fonctions des boutons :
- Le premier bouton appui sur "C" en le survolant et relâche cette touche virtuelle en sortant le curseur du bouton. En cochant Auto, on répète rapidement l'appui sur le C, imitant un vrai clavier. A tester sous un éditeur de texte par exemple.
- Le deuxième bouton tape "CV".
- Le troisième bouton tape C et V de façon plus temporisée.
- En cliquant sur n'importe quel bouton, la souris va faire toute seul un clic légèrement en haut à gauche de sa position actuelle. A tester sous Paint par exemple.
La fenêtre n'a pas de bordure, un fond légèrement transparent qui permet de la déplacer, et reste au premier plan sans prendre le focus, ce qui permet d'agir sur une autre application.
Ces fonctionnalités ne sont pas accessibles depuis Qt, et nécessitent l'utilisation de l'API Windows.
Bonjour,
C'est un projet intéressant, je vais pouvoir t'aider étant donné que j'ai développé un clavier virtuel il y a peu donc j'ai pas mal étudié la question.
D'abord, Qt ne permet pas de faire tout cela, il faut passer par l'API Windows (tu es bien sous Windows ?).
Ensuite, je n'ai pas mon code donc si personne ne le fait avant, je t'aiderai demain soir pour la partie API Windows. Ce qu'on peut déjà faire c'est faire une classe héritant de QPushButton (ou QLabel ou autre) pour ajouter le support du "mouseover", à savoir émettre des signaux lorsque la souris survole et sort. Voici ma proposition d'implémentation :
mouseoverbutton.h
#ifndef MOUSEOVERBUTTON_H
#define MOUSEOVERBUTTON_H
#include
class MouseOverButton : public QPushButton
{
Q_OBJECT
public:
explicit MouseOverButton(QWidget *parent = 0);
~MouseOverButton();
inline const bool isMouseOver();
signals:
void entered();
void leaved();
void mouseIsOver(bool over);
private:
bool mouseOver;
void enterEvent(QEvent *);
void leaveEvent(QEvent *);
private slots:
void setMouseOver(bool over);
};
inline const bool MouseOverButton::isMouseOver() {
return mouseOver;
}
#endif // MOUSEOVERBUTTON_H
mouseoverbutton.cpp
#include "mouseoverbutton.h"
MouseOverButton::MouseOverButton(QWidget *parent) :
QPushButton(parent)
{
connect(this, SIGNAL(mouseIsOver(bool)), SLOT(setMouseOver(bool)));
}
MouseOverButton::~MouseOverButton()
{
}
void MouseOverButton::enterEvent(QEvent *) {
emit mouseIsOver(true);
}
void MouseOverButton::leaveEvent(QEvent *) {
emit mouseIsOver(false);
}
void MouseOverButton::setMouseOver(bool over) {
mouseOver = over;
if (mouseOver)
emit entered();
else
emit leaved();
}
Je suis bien sous windows (le 7).
Voici ci-joint un projet, tu peux t'appuyer dessus. Il n'est quasi pas commenté alors si tu ne comprends pas quelque chose n'hésite pas.
Attention à l'exécution ! Vu qu'il tape des choses juste en passant la souris dessus ^^
Il y a les 3 boutons demandés, avec pour chacun une checkbox "auto" pour répéter le fait de le survoler. Je ne sais pas comment fonctionnent les jeux, s'ils surveillent les down/up de touche alors il n'y a pas besoin de répéter : survole = down et sortir = up (sinon en auto actuellement ça répète les down). A tester avec un éditeur de texte (il tape des C et des V).
Si tu cliques sur un bouton, ça envoie le curseur un peu plus en haut à gauche, clique, et revient. Ce n'est pas du tout fonctionnel, mais envoyer un événement clic se fait à une certaine position à spécifier, donc pas sûr que tu puisses faire quelque chose de cette idée. A tester avec Paint par exemple.
La fenêtre peut être déplacée, et elle est toujours devant mais jamais active, sinon tu perdrais focus de la fenêtre où tu essaies de l'utiliser. Elle s'ouvre en bas de l'écran au milieu de sa largeur.
Avec ça tu devrais avoir toutes les briques pour bien avancer dans ton projet.
Bon courage !
PS : Lien dans les téléchargements
J'ai essayé et ça marche sur le notepad.
Avec les jeux, c'est plus difficile car je crois que la touche en continu
est trop rapide pour eux. Avec une pause très brève entre la touche, ça pourrait marcher.
Si j'ai d'autres problèmes, je te demanderai.
Encore merci.
De rien ;) Après c'est juste un exemple, faut reprendre pas mal de choses. La vitesse de l'automatique est à 40ms, cf mouseoverbutton.cpp . Il me semble que c'est à peu près la vitesse réglée à mon clavier.
Dans un programme pour observer les événements clavier, je me suis aperçu que l'auto-repeat réel alterne les press/release ce qui semble plus logique en fait que ce que j'ai fait.
Code de l'observateur, tout basique, en console :
Widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = 0);
~Widget();
void keyPressEvent(QKeyEvent *e);
void keyReleaseEvent(QKeyEvent *e);
};
#endif // WIDGET_H
Widget.cpp
#include "widget.h"
#include
#include
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
resize(500,400);
}
Widget::~Widget()
{
}
void Widget::keyPressEvent(QKeyEvent *e)
{
qDebug() << e->key() << e->text() << "pressed";
}
void Widget::keyReleaseEvent(QKeyEvent *e)
{
qDebug() << e->key() << e->text() << "released";
}
main.cpp
#include
#include "widget.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
Je pense qu'ajouter un Up dans Widget::auto1() avant le Down traduira mieux un vrai comportement (même si le tout premier up est en trop, ce qui est sans conséquence).
void Widget::auto1()
{
sendKeyboardInputUp( 0, QChar('C').unicode(), KEYEVENTF_UNICODE);
sendKeyboardInputDown(0, QChar('C').unicode(), KEYEVENTF_UNICODE);
}
Ce que je n'arrive pas à faire c'est :
"C" pressed
"V" pressed
"V" released
"C" released
(combinaison de touche), du coup c'est juste alterné très rapidement. Bizarre, car ce comportement est possible en vrai... Il doit y avoir une question de pile quelque part.
Je maj la page de téléchargement.