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

时间:2013-05-10 05:08:59

标签: c++ qt qgraphicsview

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

我遇到的问题是水平滚动始终向上滚动0.279。这不是一个大问题,但非常烦人,而且还指出了其他错误。

所以,问题如下:

  1. 这是实现水平滚动的正确方法吗?如果没有,那是什么?
  2. 如何消除此0.279的差值?
  3. 提前致谢。

    下面的代码和示例输出
    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);
    }
    

    当在场景的左边缘时,来自scrollHorizo​​ntal中qDebug()行的示例输出:

    center:  261.5 ,  615.654 
    center:  261.5 ,  615.375 
    center:  261.5 ,  615.096 
    center:  261.5 ,  614.817 
    center:  261.5 ,  614.538 
    center:  261.5 ,  614.259 
    center:  261.5 ,  613.98 
    center:  261.5 ,  613.701 
    center:  261.5 ,  613.421 
    

1 个答案:

答案 0 :(得分:5)

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

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

在Mac上,您必须完全禁用应用程序的滚动条惯性。否则,只要松开修改器并将手指从触控板/滚轮上抬起,垂直滚动就会因惯性而继续。这将使Mac用户的体验很糟糕,他们会讨厌你:)

screenshot

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];
}

main.cpp

//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();
}