2015-11-03 6 views
1

Je rencontre un comportement inattendu dans mon code. J'ai un QGraphicsView contenant un QGraphicsScene. Maintenant, je veux détecter la molette de la souris pour faire un zoom sur la vue et déplacer la souris pour déplacer des éléments dans la scène, ce dernier uniquement lorsque le contrôleur est pressé. Maintenant j'ai deux problèmes:Comportement inattendu avec les modificateurs QMouseMoveEvent et QKeyEvent

  1. MouseMoveEvent est appelée même lorsque la souris n'est pas déplacée mais seulement la molette de la souris. Le déplacement avec et sans contrôle pressé fonctionne bien mais quand je m'arrête de bouger pendant que la commande est pressée et que je continue à utiliser la molette de la souris, non seulement le mousemoveevent est appelé, mais le modulateur est toujours actif. Quel est le problème?

main.cpp

#include "ppi.h" 
#include <QtGui/QApplication> 

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

ppi.h

#ifndef PPI_H 
#define PPI_H 

#include <QtGui/QMainWindow> 
#include <QGraphicsView> 
#include <QDebug> 
#include <QWheelEvent> 

#include "ui_ppi.h" 
#include "ppiView.h" 
#include "ppiscene.h" 

class PPI : public QMainWindow 
{ 
    Q_OBJECT 

public: 
    PPI(QWidget *parent = 0, Qt::WFlags flags = 0); 
    ~PPI(); 
    int i; 

private: 
    Ui::ppiClass ui; 
    PPIScene* ppiScene; 

protected slots: 
    void onZoom(QWheelEvent *event); 
    void onMouseMoved(QGraphicsSceneMouseEvent *event); 
}; 

#endif // PPI_H 

ppi.cpp

#include "ppi.h" 


PPI::PPI(QWidget *parent, Qt::WFlags flags) 
    : QMainWindow(parent, flags) 
{ 
    ui.setupUi(this); 

    ppiScene = new PPIScene(this); 

    connect(ppiScene, SIGNAL(mouseMoved(QGraphicsSceneMouseEvent*)), this, SLOT(onMouseMoved(QGraphicsSceneMouseEvent*))); 
    connect(ui.gVPPI, SIGNAL(zoom(QWheelEvent*)), this, SLOT(onZoom(QWheelEvent*))); 

    ppiScene->setSceneRect(0,0,1024,1024); 
    ui.gVPPI->setScene(ppiScene); 
    ui.gVPPI->setMouseTracking(true); 

    i = 0; 
} 

PPI::~PPI() 
{ 

} 



void PPI::onZoom(QWheelEvent *event) 
{ 
     if(event->delta() > 0) 
      ui.gVPPI->scale(1.01, 1.01); 
     else 
      ui.gVPPI->scale(1/1.01, 1/1.01); 
} 


void PPI::onMouseMoved(QGraphicsSceneMouseEvent *event) 
{ 
    i++; 
    qDebug() << "slot" << i << event->modifiers(); 
    if(event->modifiers() & Qt::ControlModifier) 
    { 
     qDebug() << "ctrl pressed"; 
    } 
} 

ppiview.h

#ifndef PPIVIEW_H 
#define PPIVIEW_H 

#include <QGraphicsView> 
#include <QMouseEvent> 

class PPIView : public QGraphicsView 
{ 
    Q_OBJECT 

public: 
    PPIView(QWidget * parent = 0); 
    ~PPIView(); 

private: 
    void wheelEvent(QWheelEvent *event); 

signals: 
    void zoom(QWheelEvent *event); 

}; 

#endif // PPIVIEW_H 

ppiview.cpp

#include "ppiview.h" 

PPIView::PPIView(QWidget * parent) 
    : QGraphicsView(parent) 
{ 

} 

PPIView::~PPIView() 
{ 

} 

void PPIView::wheelEvent(QWheelEvent *event) 
{ 
    emit zoom(event); 
} 

ppiscene.h

#ifndef PPISCENE_H 
#define PPISCENE_H 

#include <QGraphicsScene> 
#include <QGraphicsSceneMouseEvent> 
#include <QDebug> 

class PPIScene : public QGraphicsScene 
{ 
    Q_OBJECT 

public: 
    PPIScene(QObject *parent); 
    ~PPIScene(); 
    int i; 

private: 
    void mouseMoveEvent(QGraphicsSceneMouseEvent *event); 

signals: 
    void mouseMoved(QGraphicsSceneMouseEvent *event); 

}; 

#endif // PPISCENE_H 

ppiscene.cpp

#include "ppiscene.h" 

PPIScene::PPIScene(QObject *parent) 
    : QGraphicsScene(parent) 
{ 
    i = 0; 
} 

PPIScene::~PPIScene() 
{ 

} 

void PPIScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event) 
{ 
    i++; 
    qDebug() << "signal" << i << event->modifiers(); 
    emit mouseMoved(event); 
} 
+0

Veuillez minimiser votre code. 80% de ce que vous avez posté est complètement inutile. Dans un premier temps, mettez tout dans un seul fichier '.cpp'. C'est un cas de test, après tout. –

+0

J'ai essayé de tout mettre dans un seul fichier .cpp mais cela va causer beaucoup d'erreurs que je ne sais pas comment réparer. – honiahaka10

Répondre

1

Il est vraiment étrange. Il semble que l'état Qt :: KeyboardModifiers, que QGraphicsSceneMouseEvent :: modificateurs renvoie, n'est mis à jour que lorsque la souris est physiquement déplacée. Ce qui est encore plus étrange, c'est que dans votre code QGraphicsSceneMouseEvents de type QGraphicsSceneMouseMove sont envoyés même lorsque la souris n'est pas déplacée du tout, mais seulement la roue est tournée. Peut-être que le mouvement relatif dû à votre mise à l'échelle compte comme mouvement, mais pas comme mouvement, ce qui met à jour les modificateurs.

J'ai été capable de reproduire votre problème: L'état des modificateurs ne change pas à moins que la souris soit déplacée physiquement.

Heureusement, il existe une solution de contournement facile. Dans

void PPI::onMouseMoved(QGraphicsSceneMouseEvent *event) 
{ 
    i++; 
    qDebug() << "slot" << i << event->modifiers(); 
    if(event->modifiers() & Qt::ControlModifier) 
    { 
     qDebug() << "ctrl pressed"; 
    } 
} 

remplacer:

if(event->modifiers() & Qt::ControlModifier) 

avec:

if(QApplication::queryKeyboardModifiers() & Qt::ControlModifier) 

QApplication :: queryKeyboardModifiers() est mis à jour immédiatement lorsque vous appuyez ou relâchez la touche de commande.

+0

Merci beaucoup, ça marche parfaitement! – honiahaka10