c++ - Creating autoscroll feature in QGraphicsView -
i have qgraphicsview
, qgraphicsscene
. depending on user input qgraphicsitem
may placed on scene. item both selectable , movable.
when scene larger view scrollbars appear (they set show when necessary).
when item moved user near edge of view scene width/height stretched accordingly - making scene bigger.
the question how force scrollbars scroll scene when item near border of view? feature think common in graphic editor. in mousemoveevent
of scene making scene bigger, force sliders move , update visible rectangle accordingly.
this not work intended. thought scrolls adjusting new scene size there no smooth movement in view. there better way in doing this?
some explanations:
itemundercursor = slected qgraphicsitem qgv = qgraphicsview
code snippet:
// check if item near border qpointf point = itemundercursor->maptoscene(itemundercursor->boundingrect().topleft()); double delta = 0; if(point.x() < visiblerect.left()) { // prevent drawing outside scene itemundercursor->setpos(visiblerect.left(), itemundercursor->scenepos().y()); if(event->scenepos().x() < oldmousepos.x()-3) { // stretch scene if(qgv->horizontalscrollbar()->value() <= 0) setscenerect(qrectf(qpointf(scenerect().x() - 3, scenerect().y()), scenerect().bottomright())); /* * disable signals drawingarea in order avoid * recursive calls of mousemoveevent enabling them * handle rest of events */ this->blocksignals(true); delta = point.x() - originalrect.left(); qgv->horizontalscrollbar()->setvalue(hscrolloriginalvalue + delta); } oldmousepos = event->scenepos(); this->blocksignals(false); // update visible rectangle visiblerect = getvisiblerect(qgv); } if(point.x() + itemundercursor->boundingrect().width() > visiblerect.right()) { // prevent drawing outside scene itemundercursor->setpos(visiblerect.right() - itemundercursor->boundingrect().width(), itemundercursor->scenepos().y()); if(event->scenepos().x() > oldmousepos.x()+3) { // stretch scene if(qgv->horizontalscrollbar()->value() >= 0) setscenerect(qrectf(scenerect().topleft(), qpointf(scenerect().bottomright().x() + 3, scenerect().bottomright().y()))); /* * disable signals drawingarea in order avoid * recursive calls of mousemoveevent enabling them * handle rest of events */ delta = point.x() + itemundercursor->boundingrect().width() - originalrect.right(); this->blocksignals(true); qgv->horizontalscrollbar()->setvalue(hscrolloriginalvalue + delta); } oldmousepos = event->scenepos(); this->blocksignals(false); // update visible rectangle visiblerect = getvisiblerect(qgv); }
i doing same top , bottom border of qgraphicsview
.
it appears previous attempt terribly complicated while solution in fact easy.
instead of previous code enough write:
qgv->ensurevisible(itemundercursor);
and make sure scenerect()
not set value, rather left handled scene itself.
this allowed scene automatically adjust size accordingly items on , forced scrollbars follow moving item when outside visible rectangle of qgraphicsview
.
Comments
Post a Comment