C++ qgraphicsview水平滚动始终具有垂直增量

C++ qgraphicsview水平滚动始终具有垂直增量,c++,qt,qgraphicsview,C++,Qt,Qgraphicsview,我已经为CAD应用程序中使用的自定义画布对QGraphicsView进行了子类化。我已经成功地重新实现了QGraphicsView::wheelEvent,以检查控制键的键盘修改器,如果按下控制键,则可进行缩放。我试图在用户按住shift键并使用滚轮时实现水平滚动 我遇到的问题是水平滚动也总是向上滚动0.279。这不是一个大问题,但非常烦人,它指出了其他一些问题 因此,以下是问题: 这是实现水平滚动的正确方法吗?如果没有,是什么 如何消除0.279的增量 提前谢谢。下面是代码和示例输出 void

我已经为CAD应用程序中使用的自定义画布对QGraphicsView进行了子类化。我已经成功地重新实现了QGraphicsView::wheelEvent,以检查控制键的键盘修改器,如果按下控制键,则可进行缩放。我试图在用户按住shift键并使用滚轮时实现水平滚动

我遇到的问题是水平滚动也总是向上滚动0.279。这不是一个大问题,但非常烦人,它指出了其他一些问题

因此,以下是问题:

  • 这是实现水平滚动的正确方法吗?如果没有,是什么
  • 如何消除0.279的增量
  • 提前谢谢。下面是代码和示例输出

    void myView::zoom(int delta)
    {
        double factor = pow(1.2, delta/abs(delta));
        this->scale(factor, factor);
    }
    
    void myView::scrollHorizontal(int level)
    {
        QPointF center = mapToScene(viewport()->rect().center());
        qDebug() << "center: " << center.x() << ", " << center.y();
        centerOn(QPointF(center.x() - level, center.y()));
    }
    
    void myView::wheelEvent(QWheelEvent *event)
    {
        //qDebug() << "delta: " << event->delta();
        if (event->modifiers() & Qt::ControlModifier)
        {
            this->zoom(event->delta());
        }
        else if (event->modifiers() & Qt::ShiftModifier)
        {
            this->scrollHorizontal(event->delta());
        }
        else
            QGraphicsView::wheelEvent(event);
    }
    

    您的问题源于
    maptosene()
    处理整数而不是浮点。对于特定的视口大小,舍入误差始终指向相同的方向,因此您总是添加一些增量

    您希望直接修改滚动条的
    属性或将事件发送到水平滚动条。我已经实现了后者,它非常简单

    在Mac上,您必须完全禁用应用程序的滚动条惯性。否则,只要释放修改器并将手指从轨迹板/滚轮上提起,垂直滚动将由于惯性而继续。这会让Mac用户的体验很糟糕,他们会因此恨你:)

    gview scroll.pro

    QT       += core gui
    greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
    TARGET = gview-scroll
    TEMPLATE = app
    macx {
        LIBS += -framework Foundation
        OBJECTIVE_SOURCES += helper.m
    }
    SOURCES += main.cpp
    
    helper.m

    //helper.m
    #include <Foundation/NSUserDefaults.h>
    #include <Foundation/NSDictionary.h>
    #include <Foundation/NSString.h>
    
    void disableMomentumScroll(void)
    {
        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
        NSDictionary *appDefaults = [NSDictionary dictionaryWithObject:@"NO" forKey:@"AppleMomentumScrollSupported"];
        [defaults registerDefaults:appDefaults];
    }
    

    真奇怪。我确实发现当你到达场景矩形的边界时,
    QGraphicsView
    滚动有点“不自然”,无论可见矩形在场景矩形中的什么位置,行为都是一样的吗?虽然知道问题的原因很有趣,但从这个角度看,你所做的是非常糟糕的。如果有人想要一个水平滚动,他们可以简单地使用一个已经实现的输入设备。像所有最新的轨迹板、带滚动拨片的鼠标或多点触控鼠标等一样,大概CAD用户可以负担得起一个像样的输入设备,而您不需要提供这样的解决方法。
    //helper.m
    #include <Foundation/NSUserDefaults.h>
    #include <Foundation/NSDictionary.h>
    #include <Foundation/NSString.h>
    
    void disableMomentumScroll(void)
    {
        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
        NSDictionary *appDefaults = [NSDictionary dictionaryWithObject:@"NO" forKey:@"AppleMomentumScrollSupported"];
        [defaults registerDefaults:appDefaults];
    }
    
    //main.cpp
    #include <QApplication>
    #include <QGraphicsScene>
    #include <QGraphicsView>
    #include <QtCore/qmath.h>
    #include <QScrollBar>
    #include <QWheelEvent>
    #include <QDebug>
    
    class View : public QGraphicsView {
    public:
        void zoom(int delta) {
            double factor = qPow(1.2, delta/qAbs(delta));
            scale(factor, factor);
        }
        void wheelEvent(QWheelEvent *event) {
            if (event->modifiers() & Qt::ControlModifier) {
                zoom(event->delta());
            }
            else if (event->modifiers() & Qt::ShiftModifier) {
                horizontalScrollBar()->event(event);
            }
            else {
                QGraphicsView::wheelEvent(event);
            }
        }
    public:
        explicit View(QWidget *parent=0) : QGraphicsView(parent) {}
        explicit View(QGraphicsScene *scene, QWidget *parent=0) : QGraphicsView(scene, parent) {}
    };
    
    #ifndef Q_OS_MAC
    void disableMomentumScroll() {}
    #else
    extern "C" { void disableMomentumScroll(); }
    #endif
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        disableMomentumScroll();
        QGraphicsScene s;
        s.addEllipse(-50, -50, 100, 100, QPen(Qt::red), QBrush(Qt::gray));
        View w(&s);
        w.show();
        return a.exec();
    }