PDA

View Full Version : How to move an item on a GraphicsScene



Holy
3rd June 2008, 14:13
Hi,
II'm trying to move a GraphicsItem on a GraphicsScene using moveBy()Function but nothing moves on the screen , may someone help me to achieve this ?
Thanks in advance
here is the Programmcode i tried to write :
-------


class Container: public QGraphicsRectItem
{
public:
Container(QGraphicsItem* parent=0, intx, int y);
};
Container::Container(QGraphicsItem* parent, intx=0, int y=0): QGraphicsRectItem(parent)
{QColor color (0,0,100);
QPen p(color);
p.setWidth(2);
QBrush brush(QColor(0,160,0));
setPen(p);
setBrush(brush);
setRect()x,y,100,60;
show();
}

--------


#include"Container.h"
class Scene: public QGraphicsScene
{
public:
Scene(QWidget* parent=0);
Container*container;
};
Scene::Scene(QWidget* parent):QGraphicsScene(parent)
{
QBrush brush(QColor(180,180,220), Qt::Dense4Pattern);
setBackgroundBrush(brush);
}

--------
mainGui class


#include"include/gui/mainGui.h"
#include"include/gui/Scene.h"
#include"include/gui/container.h"
class MainGui:public QWidget
{
Q_OBJECT
public:
MainGui(QWidget*parent=0);
private:
QGraphicsScene *scene;
};
MainGui::MainGui(QWidget *parent):QWidget(parent)
{
scene=newScene(this);
Container*c1= new Container(0,0,0);
// I want the item to move step by step after any 1000 ms on the Screen
QMoveEvent *event;
int x=event->pos().x();
int y=event->pos().y();
c1->moveBy((qreal)x,(qreal)y);
startTimer(1000);
c1->addItem(c1);
scene->addLine(-5, -200, -5, 200);
scene->addLine(105, -200,105, 200);
scene->advance();
QGraphicsView *view =new QGraphicsView (scene);
QGridLayout *layout= new QGridLayout();
layout->addWidget(view);
setLayou(layout);
view->show();
}

jacek
3rd June 2008, 23:53
// I want the item to move step by step after any 1000 ms on the Screen
QMoveEvent *event;
int x=event->pos().x();
int y=event->pos().y();
c1->moveBy((qreal)x,(qreal)y);
It won't work --- you take x and y values from an uninitialized object.



startTimer(1000);
When you use startTimer(), you have to reimplement QObject::timerEvent() and put the code that you want to run every second there.

You need something like:
void MainGui::timerEvent( QTimerEvent *e )
{
Q_UNUSED( e);
scene->advance();
}
You can also consider using QTimer instead of startTimer()/timerEvent().

To make scene->advance() work, you have to reimplement QGraphicsItem::advance() in your Container class or use QGraphicsItemAnimation.

P.S. Please, don't post the same question twice in two different threads.

Holy
4th June 2008, 22:44
hi,
Sorry for the posts and thanks for your answer.
i tried to do like you said namely:
------ MainGui.cpp

MainGui::MainGui(QWidget *parent): QWidget(parent)
{
...
}
void MainGui::timerEvent(QTimerEvent *e)
{
Q_UNUSED(e);

QGraphicsItemAnimation anim;
anim.setItem(c1);

for(int i=0; i<200; i++)
{
anim.yTranslationAt(i/200.0);

}
scene->advance();
update();

}
but it doesn't work.
I also tried like this:



MainGui::MainGui(QWidget *parent): QWidget(parent)
{

//QWidget *myWidget= new QWidget();

scene = new Scene(this);

Container *c1 = new Container(0, 0, 0);

QGraphicsItemAnimation anim;
QTimeLine *timeline = new QTimeLine(5000);
anim.setItem(c1);
for(qreal i=0.0;i<200.0;i++)
{
anim.setTranslationAt(i/200.0,i,i);
anim.yTranslationAt(i/200.0);

}

anim.setTimeLine(timeline);
timeline->setUpdateInterval(1000/3);
timeline->setLoopCount(0);
timeline->setDuration(5000);
timeline->start();

}

the item doesn't move as well, please can you write it in the right way so that it can work?
thanks in advance

jacek
4th June 2008, 22:57
You create the animation object on the stack and it gets destroyed as soon as the constructor ends. Make it a member variable.

Holy
5th June 2008, 10:01
I did it, but there's no change, nothing moves.

can someone post me an example that works please?
what i want is to move the item upper in the vertical direction.
thanks for help.

Holy
5th June 2008, 10:37
it works now! thanks very much for the last idea!
but there's another problem, the item is moving down. How can i get it moving up first and then moving down and the movement should be inside the lines (i mean the item should remain inside the lines when moving) .
thanks for your help.

jacek
5th June 2008, 13:09
but there's another problem, the item is moving down. How can i get it moving up first and then moving down and the movement should be inside the lines
The movement is controlled by the animation object:

for( int i = 0; i < 50; ++i ) {
anim.setTranslationAt( i / 100.0, 0, i );
}
for( int i = 50; i < 100; ++i ) {
anim.setTranslationAt( i / 100.0, 0, 50 - i );
}

Holy
17th June 2008, 15:14
thanks for your reply;
i have another problem , while inserting items in the scene all items are added at the same time but not one after another like i want them to be added, i've tried to controll this adding action of the scene by controlling the QTimeLine of Container :

something like this:
the variable QTimeLine timeline is declared public in the class container; i use it to controll the animation of the containers.

void MainGui::addnextContainer(int i, QGraphicsScene *scene1)
{
for(int i=0;i<containerNum; i++)
{
Container*[i];
scene1->addItem(c[i]);
c[i]->timeline->start();
c[i+1]->timeline->setPaused(true);
l_items(c[i]);
c[i]->timeline->stop();
scene1->addItem(c[i+1]);
c[i+1]->timeline->start();
l_items()

}
}
puting the items in a range in the scene


QList<QGraphicsItem*>MainGui:: l_items(QGraphicsItem *item1)
{
QList<QGraphicsItem*>listing=scene->items();
listing.clear();
for(int i=0; i<listing.size();i++)
{
listing.append(item1);

}
return listing;
}
and i changed the MainGui.cpp

...
Scene scene= new Scene(this);
addnextContainer(5, scene)
...
can someone take a look at this code and tell me please what i'm doing wrong please? now i even cannot see any item anymore.
thanks in advance

jacek
20th June 2008, 15:09
What is l_items() method supposed to do? Now it just returns an empty list.

Holy
1st July 2008, 09:59
apology for the late reply, i did something else as i didn't get the solution of this problem.
back to your question.
the l_items() method is supposed to list the containers objects which are added to the scene. Can you also help me by controlling the addItem() method so that the containers should be added one by one and not all at the same time?
thanks in advance.

jacek
1st July 2008, 22:19
the l_items() method is supposed to list the containers objects which are added to the scene.
Lines 5--9 are never executed because you clear the list in line 4.


Can you also help me by controlling the addItem() method so that the containers should be added one by one and not all at the same time?
What do you mean by "one by one"? Do you want to have some kind of animation?

Holy
2nd July 2008, 09:54
the items are already animated and it works very well, but what i need now is to get control over the addItem() method of scene, so that when i add n items in the scene for instance, i should get them added one after another and not as a group of n added of course as animation.
i also tried to remove listing.clear() completely but it doesn't do anything different.

jacek
12th July 2008, 23:46
the items are already animated and it works very well, but what i need now is to get control over the addItem() method of scene, so that when i add n items in the scene for instance, i should get them added one after another and not as a group of n added of course as animation.
Would it be enough if there was some delay between calls to addItem()?


i also tried to remove listing.clear() completely but it doesn't do anything different.
Better rewrite that method from scratch.

Holy
14th July 2008, 14:46
From Guru:Would it be enough if there was some delay between calls to addItem()?

i don't understand what you mean , can you please send me the example code to compile myself and see what you exactly mean with"some delay between calls to addItem()"

I have another question concerning Qt4.3 Network. There is an example named :"blockingFortuneclient" , i've tried to run that with eclipse on window(vista) but i cannot run it succesfully. wenn i try to input a port number it breaks, i mean it doesn't enable to input the port number.Can someone tell me please what is the problem.

Another question is : can i implement a middleware of RFID-System in the same way as this example to receive Data from a RFID-Reader?
or does someone know how to implement an RFID-receiver with Qt ? i will be very thankfull if someone send me an example code.
thanks for your reply.

jacek
17th July 2008, 14:30
From Guru:Would it be enough if there was some delay between calls to addItem()?
As a result user would see that one item appears on the scene, after a while another one appears, then another and so on. Is that what you want by writing "one after another"?


what you exactly mean with"some delay between calls to addItem()
In Qt applications you usually add delay with QTimer.


I have another question concerning Qt4.3 Network. There is an example named :"blockingFortuneclient" , i've tried to run that with eclipse on window(vista) but i cannot run it succesfully. wenn i try to input a port number it breaks, i mean it doesn't enable to input the port number.Can someone tell me please what is the problem.
What "breaks" mean in exactly this case? Does the application crash or it starts properly but you can't enter anything into line edits?


Another question is : can i implement a middleware of RFID-System in the same way as this example to receive Data from a RFID-Reader?
Everything depends on the RFID reader and its drivers. Some readers have USB or RS-232C interfaces and for these you don't need any networking code.

Next time please ask unrelated questions in new threads.

Holy
18th July 2008, 11:46
Guru
As a result user would see that one item appears on the scene, after a while another one appears, then another and so on. Is that what you want by writing "one after another"?
Holy:
it's exactly what i mean .
Guru:
In Qt applications you usually add delay with QTimer.
Holy:
Isn't it possible with QTimeLine? can i get an example please?
Guru:
What "breaks" mean in exactly this case? Does the application crash or it starts properly but you can't enter anything into line edits?
Holy: I don't know what the problem was, i've just closed Eclipse and now it's alright,it's working again.
Thanks for your answer.

jacek
25th July 2008, 12:25
Isn't it possible with QTimeLine? can i get an example please?
No, because you can't control visibility with QTimeLine.

You need:

a list of items that must be added to the scene,
a slot which adds an item from the list to the scene,
QTimer which fires that slot until the list is empty.

P.S. Please, use the [quote] tags.

Holy
25th July 2008, 15:40
No, because you can't control visibility with QTimeLine.

You need:

a list of items that must be added to the scene,
a slot which adds an item from the list to the scene,
QTimer which fires that slot until the list is empty.

P.S. Please, use the [ quote ] tags.

[QUOTE=Holy;76800].
I'll try like u say. Thanks