2013-05-10 2 views
6

저는 CAD 응용 프로그램에서 사용할 사용자 정의 캔버스에 대해 QGraphicsView를 하위 클래스 화했습니다. QGraphicsView :: wheelEvent를 성공적으로 구현하여 컨트롤 키에 대한 키보드 수정자를 확인하고, 컨트롤 키를 누르면 확대/축소합니다. 사용자가 교대를 유지하고 휠을 사용할 때 가로 스크롤을 구현하려고합니다.qgraphicsview 가로 스크롤은 항상 수직 델타가 있습니다

내가 겪고있는 문제는 가로 스크롤도 항상이 0.279만큼 위로 스크롤된다는 것입니다. 커다란 문제는 아니지만 크게 괴롭 히고 다른 점을 지적합니다.

그래서, 여기에 질문이 있습니다 :

  1. 이 수평 스크롤을 구현하는 올바른 방법인가? 그렇지 않다면 무엇입니까?
  2. 이 델타 0.279는 어떻게 제거합니까?

미리 감사드립니다. scrollHorizontal에서 qDebug() 라인에서

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

샘플 출력 아래 코드 샘플 출력 할 때 장면의 왼쪽 가장자리에 :

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

이상합니다. 장면 직사각형의 범위에 도달하면 'QGraphicsView'가 약간'부자연 스러움 '으로 스크롤되는 것을 볼 수 있습니다. 가시 rect가 장면 rect에 있는지에 관계없이 같은 동작입니까? – cmannett85

+0

문제의 원인을 아는 것은 흥미로운 일이지만, 실제로하는 일은 [UX] (http://ux.stackexchange.com) 관점에서 보면별로 좋지 않습니다. 수평 스크롤을 원하면 구현 된 입력 장치를 사용할 수 있습니다. 최근의 모든 트랙 패드와 마찬가지로 스크롤 패들 또는 멀티 터치 등이있는 마우스가 있습니다. CAD 사용자는 적절한 입력 장치를 제공 할 수 있으며 이러한 대안을 제공 할 필요는 없습니다. –

답변

5

귀하의 문제는 사실에서 오는 mapToScene() 프로세스의 정수 포인트가 아니라 부동 소수점. 반올림 오류는 항상 특정 뷰포트 크기에 대해 동일한 방식으로 지정되므로 항상 델타를 추가합니다.

스크롤 막대의 value 속성을 직접 수정하거나 이벤트를 가로 스크롤 막대에 보내려합니다. 후자를 구현 했으므로 간단합니다.

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(); 
} 
을 :) 위해 그들은 당신을 싫어