QMouseMoveEvent和QKeyEvent修饰符

时间:2015-11-03 14:17:21

标签: qt qgraphicsview qgraphicsscene qkeyevent qmouseevent

我在代码中遇到意外行为。 我有一个包含QGraphicsScene的QGraphicsView。现在我想要检测鼠标滚轮以缩放视图和鼠标移动以移动场景中的项目,后者仅在按下controll时。现在我有两个问题:

  1. 即使未移动鼠标但只移动鼠标滚轮,也会调用MouseMoveEvent。

  2. 使用和不使用controll进行移动可以正常工作但是当我按下controll时停止移动并继续使用鼠标滚轮不仅会调用mousemoveevent,而且controllmodifier仍然处于活动状态。有什么问题?

  3. 的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);
    }
    

1 个答案:

答案 0 :(得分:1)

真的很奇怪。看起来Qt :: KeyboardModifiers状态(QGraphicsSceneMouseEvent :: modifiers返回的状态)仅在物理移动鼠标时更新。更奇怪的是,在你的代码中,QGraphicsSceneMouseEove类型的QGraphicsSceneMouseEvents被发送,即使鼠标根本没有移动,但只转动了轮子。也许由于你的缩放而产生的相对运动算作运动,而不是运动,它会更新修饰符。

我能够重现您的问题:修改器的状态不会发生变化,除非鼠标是物理移动的。

幸运的是,有一个简单的解决方法。在

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

取代:

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

使用:

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

当您按下或释放控制键时,QApplication :: queryKeyboardModifiers()会立即更新。