2013-05-10 4 views
6

Ich habe QGraphicsView für ein benutzerdefiniertes Zeichenfeld subclasiert, das in einer CAD-Anwendung verwendet werden soll. Ich habe erfolgreich QGraphicsView :: wheelEvent implementiert, um die Tastaturmodifikatoren für den Steuerschlüssel zu überprüfen und, wenn die Steuertaste gedrückt wird, zu zoomen. Ich versuche, eine horizontale Bildlauf zu implementieren, wenn der Benutzer Schicht hält und das Rad verwendet.qgraphicsview horizontales Scrollen hat immer ein vertikales Delta

Das Problem, das ich habe, ist, dass die horizontale Scrolling auch immer scrollt bis 0,279. Kein großes Problem, aber sehr ärgerlich und es deutet darauf hin, dass etwas anderes falsch ist.

So, hier sind die Fragen:

  1. Ist dies der richtige Weg horizontales Scrollen zu implementieren? Wenn nicht, was ist?
  2. Wie kann ich dieses Delta von 0,279 eliminieren?

Vielen Dank im Voraus. Code und Beispielausgabe unter

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

Beispielausgabe des qDebug() Linie in scrollHorizontal wenn am linken Rand der Szene:

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 
+0

Das ist seltsam. Ich finde den 'QGraphicsView' etwas" unnatürlich "scrollend, wenn Sie die Grenzen des Szenenrechtecks ​​erreichen, ist das Verhalten gleich, egal wo sich das sichtbare Rect in der Szene befindet? – cmannett85

+0

Es wäre zwar interessant zu wissen, was das Problem verursacht, aber was Sie tun, ist aus der Perspektive von [UX] (http://ux.stackexchange.com) ziemlich schlecht. Wenn jemand einen horizontalen Bildlauf wünscht, kann er einfach ein Eingabegerät verwenden, auf dem es implementiert ist. Wie alle neueren Trackpads, Mäuse mit Scroll-Paddles oder Multitouch, etc. Vermutlich kann sich ein CAD-Benutzer ein ordentliches Eingabegerät leisten, und Sie müssen keine solchen Workarounds anbieten. –

Antwort

5

Ihr Problem kommt von der Tatsache, dass mapToScene() Prozesse eine ganze Zahl Punkt, kein Gleitpunkt. Der Rundungsfehler wird für eine bestimmte Ansichtsfenstergröße immer auf die gleiche Weise angezeigt, daher fügen Sie immer ein Delta hinzu.

Sie möchten die Eigenschaft value der Bildlaufleiste direkt ändern oder das Ereignis an die horizontale Bildlaufleiste senden. Ich habe letzteres implementiert, es ist einfach genug.

Auf einem Mac müssen Sie die Trägheit der Bildlaufleiste für Ihre Anwendung unbedingt deaktivieren. Andernfalls, sobald Sie den Modifikator loslassen und Ihren Finger vom Trackpad/Scrollrad nehmen, wird das vertikale Scrollen aufgrund der Trägheit fortgesetzt. Dies würde Erfahrung saugen Mac-Anwender machen und sie würden Sie hassen es

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