qt - Snapping to grid doesn't work -
i trying snapping on grid such whatever draw should take gridpoints , no other points. have made grid in cadgraphicsscene.cpp , made different class snapping. grid made follows:
cadgraphicscene.cpp
void cadgraphicsscene::drawbackground(qpainter *painter, const qrectf &rect) { const int gridsize = 50; const int realleft = static_cast<int>(std::floor(rect.left())); const int realright = static_cast<int>(std::ceil(rect.right())); const int realtop = static_cast<int>(std::floor(rect.top())); const int realbottom = static_cast<int>(std::ceil(rect.bottom())); // draw grid. const int firstleftgridline = realleft - (realleft % gridsize); const int firsttopgridline = realtop - (realtop % gridsize); qvarlengtharray<qline, 100> lines; (qreal x = firstleftgridline; x <= realright; x += gridsize) lines.append(qline(x, realtop, x, realbottom)); (qreal y = firsttopgridline; y <= realbottom; y += gridsize) lines.append(qline(realleft, y, realright, y)); painter->setpen(qpen(qcolor(220, 220, 220), 0.0)); painter->drawlines(lines.data(), lines.size()); // draw axes. painter->setpen(qpen(qt::lightgray, 0.0)); painter->drawline(0, realtop, 0, realbottom); painter->drawline(realleft, 0, realright, 0); }
my snap class looks follows:
snap.cpp
#include "snap.h" #include <qapplication> snap::snap(const qrect& rect, qgraphicsitem* parent, qgraphicsscene* scene): qgraphicsrectitem(qrectf()) { setflags(qgraphicsitem::itemisselectable | qgraphicsitem::itemismovable | qgraphicsitem::itemsendsgeometrychanges); } void snap::mousepressevent(qgraphicsscenemouseevent *event){ offset = pos() - computetopleftgridpoint(pos()); qgraphicsrectitem::mousepressevent(event); } qvariant snap::itemchange(graphicsitemchange change, const qvariant &value) { if (change == itempositionchange && scene()) { qpointf newpos = value.topointf(); if(qapplication::mousebuttons() == qt::leftbutton && qobject_cast<cadgraphicsscene*> (scene())){ qpointf closestpoint = computetopleftgridpoint(newpos); return closestpoint+=offset; } else return newpos; } else return qgraphicsitem::itemchange(change, value); } qpointf snap::computetopleftgridpoint(const qpointf& pointp){ cadgraphicsscene* customscene = qobject_cast<cadgraphicsscene*> (scene()); int gridsize = customscene->getgridsize(); qreal xv = floor(pointp.x()/gridsize)*gridsize; qreal yv = floor(pointp.y()/gridsize)*gridsize; return qpointf(xv, yv); }
snap.h
#ifndef snap_h #define snap_h #include <qgraphicsrectitem> #include "cadgraphicsscene.h" class snap : public qgraphicsrectitem { public: snap(const qrect& rect, qgraphicsitem* parent, qgraphicsscene* scene); protected: void mousepressevent(qgraphicsscenemouseevent *event); qvariant itemchange(graphicsitemchange change, const qvariant &value); private: qpointf offset; qpointf computetopleftgridpoint(const qpointf &pointp); }; #endif // snap_h
but nothing happened, no snapping done. can please me in above?
one of problems pass qrect()
qgraphicsrectitem
constructor in initialization list of snap
class. means have 0 width , height. instead pass same qrect
object pass snap constructor:
snap::snap(const qrect& rect, qgraphicsitem* parent, qgraphicsscene* scene) : qgraphicsrectitem(rect)
you don't seem use parent , scene arguments might leave them out:
snap::snap(const qrect& rect) : qgraphicsrectitem(rect)
or if plan use parent can set default value 0 in declaration:
snap(const qrect& rect, qgraphicsitem* parent = 0);
then pass them both base class constructor:
snap::snap(const qrect& rect, qgraphicsitem* parent) : qgraphicsrectitem(rect, parent)
snap.h
#ifndef snap_h #define snap_h #include <qgraphicsrectitem> class snap : public qgraphicsrectitem { public: snap(const qrect &rect, qgraphicsitem *parent = 0); protected: void mousepressevent(qgraphicsscenemouseevent *event); qvariant itemchange(graphicsitemchange change, const qvariant &value); private: qpointf offset; qpointf computetopleftgridpoint(const qpointf &pointp); }; #endif // snap_h
snap.cpp
#include "snap.h" #include <qdebug> #include <qmath.h> snap::snap(const qrect& rect, qgraphicsitem* parent) : qgraphicsrectitem(rect, parent) { setflags(qgraphicsitem::itemisselectable | qgraphicsitem::itemismovable | qgraphicsitem::itemsendsgeometrychanges); } void snap::mousepressevent(qgraphicsscenemouseevent *event){ offset = pos() - computetopleftgridpoint(pos()); qgraphicsrectitem::mousepressevent(event); } qvariant snap::itemchange(graphicsitemchange change, const qvariant &value) { qdebug()<<"inside itemchange"; if (change == itempositionchange && scene()) { qpointf newpos = value.topointf(); qpointf closestpoint = computetopleftgridpoint(newpos); return closestpoint+=offset; } else return qgraphicsitem::itemchange(change, value); } qpointf snap::computetopleftgridpoint(const qpointf& pointp){ int gridsize = 100; qreal xv = qfloor(pointp.x()/gridsize)*gridsize; qreal yv = qfloor(pointp.y()/gridsize)*gridsize; return qpointf(xv, yv); }
mainwindow.cpp
#include "mainwindow.h" #include "ui_mainwindow.h" #include <qgraphicsview> #include <qlayout> #include "snap.h" mainwindow::mainwindow(qwidget *parent) : qmainwindow(parent), ui(new ui::mainwindow) { ui->setupui(this); centralwidget()->setlayout(new qvboxlayout); qgraphicsview *view = new qgraphicsview(this); centralwidget()->layout()->addwidget(view); snap *snap = new snap(qrect(0,0,100,100)); view->setscene(new qgraphicsscene); view->scene()->additem(snap); } mainwindow::~mainwindow() { delete ui; }
Comments
Post a Comment