c++ - qgraphicsview horizontal scrolling always has a vertical delta -
i've subclassed qgraphicsview custom canvas used in cad application. i've reimplemented qgraphicsview::wheelevent check keyboard modifiers control key and, if control key pressed, zoom. i'm trying implement horizontal scroll when user holds shift , uses wheel.
the problem i'm having horizontal scrolling always scrolls 0.279. not huge problem, hugely annoying , points else being wrong.
so, here questions:
- is right way implement horizontal scrolling? if not, is?
- how eliminate delta of 0.279?
thanks in advance. code , sample output below
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); }
sample output qdebug() line in scrollhorizontal when @ left-edge of scene:
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
your issue comes fact maptoscene()
processes integer point, not floating point point. rounding error pointed same way particular viewport size, add delta.
you want directly modifying scroll bar's value
property or sending event horizontal scroll bar. i've implemented latter, it's simple enough.
on mac, must absolutely disable scrollbar inertia application. otherwise release modifier , lift finger off trackpad/scroll wheel, vertical scrolling continue due inertia. make mac users' experience suck , hate :)
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(); }
Comments
Post a Comment