PDA

View Full Version : QGraphicsView, QGraphicsItem, QGraphicsScene



Shuchi Agrawal
30th January 2007, 10:37
hi,
can anyone make me clear with the difference b/w QGraphicsView, QGraphicsItem and QGraphicsScene . i studied fm the documentation but still i m not clear how to use them.
i want to draw a line on a menu click or when i click at a point n drag n release. so where to write code for this? in QGraphicsView, QGraphicsItem or QGraphicsScene ?
thanks in advance :)

Gopala Krishna
30th January 2007, 12:04
hi,
can anyone make me clear with the difference b/w QGraphicsView, QGraphicsItem and QGraphicsScene . i studied fm the documentation but still i m not clear how to use them.
i want to draw a line on a menu click or when i click at a point n drag n release. so where to write code for this? in QGraphicsView, QGraphicsItem or QGraphicsScene ?
thanks in advance :)
GraphicsView framework is pretty well organised and documentation is also good. You only need to read, do the examples and tutorials.
Anyway to put it in simple words QGraphicsScene is the offscreen container for QGraphicsItem's. QGraphicsItem are objects that represent the shapes or anything to be drawn and managed. QGraphicsView is the viewer widget which enables to "view" the scene.

For your second question
Just create QGraphicsView and QGraphicsScene in your mainwindow constructor like this


MainWindow::MainWindow()
{
QGraphicsView *view = new QGraphicsView(this);
// Here scene is supposed to be member variable since u need it later
// also you can give any geometry of scene
scene = new QGraphicsScene(0,0,1024,800);
view->setScene(scene);
...
}

Now just create QGraphicsLineItem's when you need to draw line. For eg assuming the below slot to be called from menu do the following

MainWindow::slotOnMenuClick()
{
QGraphicsLineItem *line = new QGraphicsLineItem( required line);
scene->addItem(line);
}

Drawing lines on clicking and dragging needs you to reimplement QGraphicsScene and in that reimplement mouse*Events() which will require some knowledge about the framework. Go through the examples and documentation.

Shuchi Agrawal
30th January 2007, 12:23
hey thanks a lot but i m able to draw line son clicking n all but i m unable to map the coordinates and this is where i need help. as u said tht in QGraphicsScene i need to write the code.. so i wil implement n let u know how much i succeeded..

Shuchi Agrawal
31st January 2007, 11:39
hi,
can anyone help m enderstanding the concept of coordinates for QGraphicsView, QGraphicsItem, QGraphicsScene (i hv read the Qt doc bt still not able to nderstand)..

graphicsView = new QGraphicsView(centralwidget);
graphicsView->setGeometry(QRect(0, 0, 250, 250));

scene = new QGraphicsScene();
scene->setSceneRect(0,0,250,250);
view->setScene(scene);

QGraphicsLineItem *line = new QGraphicsLineItem(10.0,10.0,50.0,50.0);
line->setFlag( QGraphicsItem::ItemIsMovable );
scene->addItem(line);

what is the relationship of the 3 coordinates given in 3 diff lines of code?

Gopala Krishna
31st January 2007, 17:10
(i hv read the Qt doc bt still not able to nderstand)
Qt docs aren't that bad. I hope you have read this (http://doc.trolltech.com/4.2/graphicsview.html). Go through them slowly and just experiment by writing small programs. For eg you can write a small program and reimplement QGraphicsItem, QGraphicsScene and then just output the coordinates wherever you feel. You can alo try rotating items on right click for eg to get feel of coordinate system.


hi,
can anyone help m enderstanding the concept of coordinates for QGraphicsView, QGraphicsItem, QGraphicsScene .

If you didn't understand from reading this (http://doc.trolltech.com/4.2/graphicsview.html).

Each entity (Item,View and Scene) have their own coordinate sytem for convienience.
The coordinate system of QGraphicsItem is for the item to mange itself locally. boundingRect(), paint() , shape() .. all functions makes one really easy to implement them since you just need to use local(Item's) coordinates.
For eg if you are implementing a card game and card being derived from QGraphicsItem.
Lets assume size of card to 100 pixels by 80 pixels.
Then

QRectF Card::boundingRect()
{
// The following is just according to local coordinates centred at (0,0)
return QRectF( -50,-40,100,80);
}
void Card::paint(QPainter *p,..)
{
p->drawRect(QRectF(-50,-40,100,80));
...
}
Now the coordinates specified in above are item's coordinates. You need not bother about where exactly is the item present on scene and hence not to bother with scene at all while implemeting any item. This is huge advantage since you can easily do all kinds of transformations (rotations,shearing,scaling..) on single item. So you can infact have any item ,for example a line, be rotated on right click and to do this you just need to write maximum of three lines of code in mousePressEvent() which would otherwise made you to do all calculations to required coordinates all by yourself and then maintain the item in that angle , you can imagine more!!!!

On the other hand scene coordinate system is used to manage all items globally. For eg you can rotate all items in scene by just setting appropriate QMatrix. Updating scene will update all the views (any no of views can have same scene) and hence if you do transformations to scene, all views will have transformations.

Doing transformation on view will just transform everything only in that view.In short you can easily transform individual items, just particular view or the scene(all views).


Hope now you get some idea about coordinate system in The GraphicsView Framework.



graphicsView = new QGraphicsView(centralwidget);
graphicsView->setGeometry(QRect(0, 0, 250, 250));

scene = new QGraphicsScene();
scene->setSceneRect(0,0,250,250);
view->setScene(scene);

QGraphicsLineItem *line = new QGraphicsLineItem(10.0,10.0,50.0,50.0);
line->setFlag( QGraphicsItem::ItemIsMovable );
scene->addItem(line);

what is the relationship of the 3 coordinates given in 3 diff lines of code?

View's geometry is just geometry of Widget.
Scene rect is geometry of scene - size of canvas.
The coordinates you are giving in constructor of line is just the start and end pos of line in 'scene' coordinates. Here don't get confused between item and scene coordinates. To specify position of item you should give the location of item on scene. Remember item coordinates are used while overriding QGraphicsItem while the location of item on scene is provided by scene coordinates.

Shuchi Agrawal
1st February 2007, 12:24
hi Gopala,
thanks a lot for ur valuable help. i m able to make out the difference.now i want to zoom an item. i m able to do that but in zooming the item i want tht whatever part of that item i click, should be zoomed(obviously with the item itself) and displayed..
i m attaching some screen shots.
problem 1:
the initial execution is shot1.now when i m right clicking on the circle then its zooming as in shot2. but if i want to click on east south corner of the circle then tht part shd be seen on the view not the west north part as i have shown in shot3.. plz see to it..


void Item::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
if (event->buttons() & Qt::RightButton)
{
delta1+=0.2;
scale(delta1,delta1);
ensureVisible((event->pos()).x(),(event->pos()).y(),50,50,50,50);
//setPos((event->pos()).x(),(event->pos()).y());
}
else
QGraphicsItem::mousePressEvent(event);
//p1 = event->buttonDownScenePos(Qt::LeftButton);
}

QRectF Item::boundingRect() const
{ return QRectF(0,0,60,60); }

QPainterPath Item::shape() const
{ QPainterPath path;
path.addEllipse(5, 5, 50, 50);
return path; }

problem 2:
when i m clicking "draw" then i m getting shot4. but when i m moving different items like square,circle,line,coloured ellipse or QGraphicsTextItem("shuchi") then many times the other item which is not clicked also get moved. why???? :(


void MainWindow::draw()
{
QGraphicsLineItem *line = new QGraphicsLineItem(10.0,10.0,50.0,50.0);
line->setFlag( QGraphicsItem::ItemIsMovable );
scene->addItem(line);

QGraphicsRectItem *rect = new QGraphicsRectItem(0, scene);
rect->setRect(60,60,90,90);
rect->setFlag( QGraphicsItem::ItemIsMovable );

QGraphicsEllipseItem *ellipse = new QGraphicsEllipseItem( 0, scene );
ellipse->setRect( 50, 50, 50, 50 );
ellipse->setFlag( QGraphicsItem::ItemIsMovable );

text1 = new MyTextItem("Shuchi", 0, scene);
text1->setPos(150,150); }

886

alitoh
23rd March 2011, 18:37
Hello.

First of all, sorry for reviving a VERY old thread, but I felt that expanding on a thread that already revolves around my issue would be better than increasing the size of the search results. If, for any reason, this is unapropiate behaviour, please do leet me know.

Now to my problem.

I'm trying, on a very simple graphic, to explain, as intuitively as possible, how QGraphicsScene - QGraphicsView and QGraphicsItem work together and relate themselves with each other. The reason for this is that I feel that, at times, QT's documentation can be too technical. While that is indeed the right thing to do, this might be annoying at times, so I'm writting my own "Guide to" QT to also teach myself in the process.

Please, look at this picture:

6125

Is my understanding of them wrong? How would you improve on that?

As always, if I'm coming short on data or on explaining myself, let me know.

Thanks in advance for your help.

A.

stampede
23rd March 2011, 18:56
I think you got it right.
Scene is just a container for managing graphics items, and rendering it with QGraphicsView is one of possible methods to visualize scene's content (you can render it with QPainter attached to any paint device).
Maybe this is not very good example, but anyway - when you are at theater, actors are QGraphicsItems, scene is QGraphicsScene and each one of spectators is a separate QGraphicsView ( seeing the scene in slightly different way ).

wysota
23rd March 2011, 19:10
I always tell to my students that the scene is the world, the view is the window they're looking through at the world and the items are things that are part of the world that one sees through the window. The world is self-sufficient (you don't need to have any windows for the world to be there and be useful) and objects in the world form hierarchies where children are positioned in a "local world" of their parent -- like people on Earth, Earth in the Solar System, Solar System in the Milky Way, Milky Way in the local cluster of galaxies, etc. And people don't care that Milky Way rotates around the centre of the local cluster, they use local coordinates relative to the Earth exactly the same way as items in the scene don't care about surroundings of its parent and use local coordinates relative to their parent.

alitoh
23rd March 2011, 19:22
Thank you for your answers!

To extend on this issue a little bit more.

Are the QGraphicsScene coordinates relative to the Dlg window? That is; the single pixel left-top corner below the dialog bar, 0,0, is also the Scene's 0,0?

wysota
23rd March 2011, 20:50
Again, QGraphicsScene is the world. The widget (view) is a window in a house. Coordinates of the world are not relative to the window in the house because the house may not even exist. Of course it is possible to map coordinates of each place in the world relative to the glass in the window in the house provided the window in the house exists. This is called a projection and its properties change if you come closer or move away from the window surface. This doesn't change the world (scene) in any way although if you change your position, you see a different part of the world. So to answer your question the top-left corner of the window is not the top-left corner of the world.