PDA

View Full Version : QGraphics View



Vivek1982
27th January 2014, 12:27
Dear All,

I have developed a application using QGraphicsScene and QGraphicPixmapItem. In the application I'm adding pixmaps on the graphic scene. Initially I'm inserting
Pixmap based on timer event for 1 seconds. On the same scene I need to insert second pixmap manually by pushbutton event. Im sharing the code here.plz help me, where I'm making mistake. I have attached output screen shot also.


SERVER::SERVER(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::SERVER)
{
ui->setupUi(this);

scene=new QGraphicsScene(0,0,740,400);
scene=new QGraphicsScene(ui->graphicsView);

int x=50;
int y=50;

timer.start(1000);

//other declarations line edit, push buttons
}

void SERVER::timeout_123()
{

x=x+2;
y=y+2;
QPixmap pix(":/t23_1.png");
QGraphicsPixmapItem *pix1= scene->addPixmap(pix);
ui->graphicsView->setScene(scene);
pix1->setPos(x,y);


}

void SERVER::on_pushButton_clicked()
{
qDebug("inserting new item");
QPixmap pix2(":/pin30_red.png");
QGraphicsPixmapItem *GIpix2= scene->addPixmap(pix2);
ui->graphicsView->setScene(scene);
GIpix2->setPos(650,150);

}


If i compile this code, initial timer based pixmap and pushbutton clicked pixmap will loaded onto the scene. In the Timer event Im incrementing setPos coordinated by 2 for every 1 second. Here on the scene, timer based pixmap is getting shifting in position but clear movement of image is not there somewat blurred.Any problem in the decalration?

Thanks in Advance.

anda_skoa
27th January 2014, 13:44
There is a couple of weird things in your code:

- you create two QGraphicScene instances but use the same variable, so the first instance is just leaked
- you define to local variables x and y, maybe you wanted to initialized the members x and y?
- you repeatedly call view->setScene(), just do that once in the constructor

Now regarding your problem: what are you expecting to get? The screenshot looks correct, several pixmaps with small offsets following a line towards bottom right, just like the offset is calculated.

Cheers,
_

Vivek1982
27th January 2014, 15:02
thanks for the reply.... actually my output should look like the timer based pixmap should be shifting by setpos not multiple pixmaps as of screenshot now. in between if i insert one more pixmap by button click event ... even that should be there at mentioned pos... and also the timer pixmap should be shifting without multiple pixmap just like a moving image on the scene.how to get this....
thanks

anda_skoa
27th January 2014, 19:17
actually my output should look like the timer based pixmap should be shifting by setpos not multiple pixmaps as of screenshot now.

If you add a new pixmap every time the timer fires, you get a new pixmap every time the timer fires. Seems pretty obvious, no?

So if you don't want to end up with one pixmap per timer event, don't add new pixmaps in the slot handling the timer's signal.

If you want to move an already existing pixmap, call its setPos() method.

Cheers,
_

Vivek1982
28th January 2014, 00:57
ok... u mean to say...in timer slot just call only setpos not add pixmap or set scene etc.... write all code in constructor only setpos in timer slot.
regarding setscene(scene ).that should be also written in timer slot or not and same at button click event.... or i need to write complete code at constructor and just call setpos in timer slot and add pixmap in button click slot.is this okay

anda_skoa
28th January 2014, 08:37
ok... u mean to say...in timer slot just call only setpos not add pixmap or set scene etc.... write all code in constructor only setpos in timer slot.

Yes



regarding setscene(scene ).that should be also written in timer slot or not

It just has to be called once, so right after constructing the scene is a good place.


or i need to write complete code at constructor and just call setpos in timer slot and add pixmap in button click slot.is this okay

You don't need to write "complete code" in the constructor, just what makes sense there. Since you create the scene in the constructor, setting it on the view is a logical next step right there.

If the scene always contains the pixmap that is moved by the timer, then add it in the constructor.
If the pixmap is not added before the first timer, then add it in the timer slot, but only once. Any further call to the timer slot then just moves it.

Cheers,
_

Vivek1982
28th January 2014, 08:53
Hi.. I tried your suggestion, program compiles but it gets hang and suggests me to close the application. I had given view->setscene(scene) directly only once in the constructor. pixmap was not moving on the view bith timer based Pixmap and button click pixmap, Please have a look. Now the code is almost same but timer based pixmap and click event based pixmap both appears but the issue is. Timer based pixmap is coming like route trace mutilple images(as shown in the earlier posted image). Im searching how to set initially at the constructor level and just to call SetPos at timer slot on the graphicitempixmap.

regarding the x,y co-ordinates, points are coming at client side. by getting the values of x,y at timer interval,it has to update on the application screen.

In my code what changes are expected, to move the timer pixmap without continous adding og pixmap and inserting click based pixmap on the scene.


SERVER::SERVER(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::SERVER)
{
ui->setupUi(this);

scene=new QGraphicsScene(0,0,740,400);
scene=new QGraphicsScene(ui->graphicsView);

timer.start(2000);
...............connection signal slot on timer out.....

void SERVER::timeout_123()
{

x=x+2;
y=y+2;
QPixmap pix1(":/t23_1.png");
QGraphicsPixmapItem *GIpix1=scene->addPixmap(pix1);
ui->graphicsView->setScene(scene);
GIpix1->setPos(x,y);
}

void SERVER::on_pushButton_clicked()
{
qDebug("inserting new item");
QPixmap pix2(":/pin30_red.png");
QGraphicsPixmapItem *GIpix2= scene->addPixmap(pix2);
ui->graphicsView->setScene(scene);
GIpix2->setPos(650,150);

}




#ifndef SERVER_H
#define SERVER_H

#include <QMainWindow>
#include <QPushButton>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QBrush>
#include <QGraphicsItem>
#include <QGraphicsPixmapItem>
#include <QTimer>
#include <QDebug>
#include <QPixmap>


class SERVER : public QMainWindow {
Q_OBJECT
public:
SERVER(QWidget *parent = 0);
~SERVER();



protected:
void changeEvent(QEvent *e);

private:
Ui::SERVER *ui;
QGraphicsView *view;
QGraphicsScene *scene;
QPixmap *pix1,*pix2;
QGraphicsItem *GIpix1,*GIpix2;
QTimer *timer;
unsigned int x,y;

private slots:
void on_pushButton_clicked();
};

#endif // SERVER_H

anda_skoa
28th January 2014, 13:09
Your code has not changed at all. Maybe you posted the wrong version again?

Cheers,
_

Vivek1982
28th January 2014, 17:18
no...actually i tried alot ... the program was getting hang.... my query is on my timer slot i can add pixmap in scene... but how to declare in constructor or writing full code in constructor and just call setpos in timer slot.if i do that program will hang...that is the reason for posting same code to suggest me.

or i need to write like graphics pixmap item = new graphics pixmap item(pixmap(location of pixmap).
next add item to scene.and setpos in timer slot... Im checking how to do it... Im trying all methods either by addpixmap in timer slot ,multiple pixmap will come or application gets hang... how to do it ?

Added after 1 50 minutes:

if any changes to be made in timer slot.plz let me know in procedures
i will try on it.

anda_skoa
28th January 2014, 18:02
no...

Yes, which you even say yourself here


actually i tried alot ... the program was getting hang.... my query is on my timer slot i can add pixmap in scene... but how to declare in constructor or writing full code in constructor and just call setpos in timer slot.if i do that program will hang...that is the reason for posting same code to suggest me.


If you just post the same code again, there is no new information for anyone reading this thread.
So it was basically a useless posting. Well actually worse, because it needed another reply just and another useless posting and this reply.

It might very well be that your changed code runs into an error, but without that code it is impossible to help you solve that error.



or i need to write like graphics pixmap item = new graphics pixmap item(pixmap(location of pixmap).
next add item to scene.and setpos in timer slot

That's what I wrote, isn't it.


if any changes to be made in timer slot.plz let me know in procedures
i will try on it.

Ok, again: add the pixmap to the scene in the constructor. Move it in the timer slot.

Cheers,
_

Vivek1982
28th January 2014, 18:23
no actually same code after changing in constructor and program is getting hang..how to approach now

ok..sorry .....i will try on your suggestion ...plz can u tel me in procedures how to do it....with same code can we modify or new code to be written.

Vivek1982
29th January 2014, 09:31
Hi.. I have changed the code as per your suggestion but still program is getting hang, Initiallty I have created scene and on top of it loaded view. Based on logic of my application I created PIXMAP, GraphicsPixmapItem. On the created pointer of GraphicItem I'm calling the PIXMAP to set on the scene, calling setscene.

In the Timer slot im calling setpos action to insert the Pixmap. Still Im confused, what as gone wrong. Even my button click Pixmap is not working now..


SERVER::SERVER(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::SERVER)
{
ui->setupUi(this);

scene=new QGraphicsScene(0,0,740,400);
scene=new QGraphicsScene(ui->graphicsView);
QPixmap pix1(":/t23_1.png");
QGraphicsPixmapItem* GIpix1= new QGraphicsPixmapItem;
scene->addPixmap(pix1);
GIpix1->setPixmap(pix1);

ui->graphicsView->setScene(scene);
timer.start(2000);
...............connection signal slot on timer out.....

void SERVER::timeout_123()
{

x=x+2;
y=y+2;
GIpix1->setPos(x,y);
}

void SERVER::on_pushButton_clicked()
{
qDebug("inserting new item");
QPixmap pix2(":/pin30_red.png");
QGraphicsPixmapItem *GIpix2= scene->addPixmap(pix2);
ui->graphicsView->setScene(scene);
GIpix2->setPos(650,150);

}





#ifndef SERVER_H
#define SERVER_H

#include <QMainWindow>
#include <QPushButton>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QBrush>
#include <QGraphicsItem>
#include <QGraphicsPixmapItem>
#include <QTimer>
#include <QDebug>
#include <QPixmap>


class SERVER : public QMainWindow {
Q_OBJECT
public:
SERVER(QWidget *parent = 0);
~SERVER();



protected:
void changeEvent(QEvent *e);

private:
Ui::SERVER *ui;
QGraphicsView *view;
QGraphicsScene *scene;
QPixmap *pix1,*pix2;
QGraphicsItem *GIpix1,*GIpix2;
QTimer *timer;
unsigned int x,y;

private slots:
void on_pushButton_clicked();
};

#endif // SERVER_H

anda_skoa
29th January 2014, 09:33
Ah, that's better.

1) you are still creating two scenes, leaking the first one
2) you are assigning the GraphicPixmapItem pointer to a local variable instead of the member that you are using in the timer slot

Cheers,
_

Vivek1982
29th January 2014, 11:32
Plz can u suggest now. what I need to do.. which line of code Im stuck up.. First I need to ask is..
1.I have wriiten a code but while calling setpos in timer slot. Just GIPix->SetPos(x,y).will work or wat declaring al other logic in constructors. Always my application is getting hang.

2.As suggested earlier post. In the timer slot,If i add pixmap to scene, that will come continous on veiw, or If i write in the constructor It will get hanged..

plz correct me in code. where is my fault

anda_skoa
29th January 2014, 12:56
plz correct me in code. where is my fault

We can only correct you code if you post the code. As long as you refuse to make any of the suggested adjustments and post the updated code, there is nothing further we can do.
Repeating the very same suggested over and over will lead nowhere.

Cheers,
_

P.S.: You keep on claiming that you have done the changes and that you observe your application "hanging", but I start to doubt whether you actually have done anything at all and just use the "hanging" as an excuse.

Vivek1982
29th January 2014, 14:01
sorry Im trying all changes to be made and compile all the time ... now Im checking line wise to address your suggestion like calling scene twice and timer slot member...please validate the logic for my application.then i will fix it....

1. initially create scene in constructor.
2.load on to veiw
3.create pixmap
4.create graphics pixmap item pointer on it add the scene and pixmap.
5.set the scene on graphics veiw
6.on timer slot call for the item setpos.

if this logic is fine?i will work out to fix this

thanks

anda_skoa
29th January 2014, 18:37
Yes, that sounds good.

I think 2 and 5 are actually the same thing, though :)

Cheers,
_

Vivek1982
30th January 2014, 09:30
Thanks for your inputs on my code. Finally I was able to resolve one mistake is that I was calling setscene twice or many times. Now coming for second problem, moving the Pixmap. I have created scene and setscene on constructor only.When coming to timer slot. code follows


ui->setupUi(this);
server=new QTcpServer(this);


scene=new QGraphicsScene(0,0,740,400);
ui->graphicsView->setScene(scene);

x=100;
y=150;

timer=new QTimer;
timer->start(4000);

connect(timer,SIGNAL(timeout()),this,SLOT(timeout_ 123()));

void SERVER::timeout_123()
{

x=x+4;
y=y+4;

QGraphicsPixmapItem *GIPix1= new QGraphicsPixmapItem(QPixmap(":/t23_1.png"));
scene->addItem(GIPix1);
GIpix1->setPos(x,y);

}



Even I had told click based Pixmap insertion, that is also done.. THE ONLY issue is now to avoid multiple Pixmap appearing on screen based on timer slot. If write code like calling all declaration in conctrusctor and just only GIPix1->setPos(x,y) in Timer Slot. Application will not work.
You had suggested me to check on the local variable initilization instead of slot members, here im fully confused, Totally IM Lost, I'm not getting any ideas beyond this.plz provide solution on this to me.

If I remove scene->addItem(GIPix1), the program will not run only..So in timer slot I have given both scene add and setpos on PixmapItem pointer.
Even gave attempt to check all the possibilities,can we give like scene->setPixmap in timer slot instead of scene->addItem.no that is not there. or still calling another slot just to setpOS, even that didnt work.. I'm fully lost.I need a solution for this. please:)

Thanks in advance

anda_skoa
30th January 2014, 15:35
You have a member variable called GIpix1 of type QGraphicsItem*, see posting #12 http://www.qtcentre.org/threads/57811-QGraphics-View?p=258156#post258156

In the same post you have the following code in the constructor


QGraphicsPixmapItem* GIpix1= new QGraphicsPixmapItem;
scene->addPixmap(pix1);
GIpix1->setPixmap(pix1);

What you do here is create a local variable with the nam GIpix1, the member variable with the same name stays uninitialized. This is why you get a problem in the timer slot when you access the member variable again.

So the newly created item pointer needs to be stored in the member variable



GIpix1 = scene->addPixmap(QPixmap(":/t23_1.png"));


Cheers,
_

Vivek1982
30th January 2014, 16:04
Im sorry.plz can u give solution for this in coding.. Im totally mad... Im trying all the methods .. but nothing is going to work out i know but still. for time being i need to do it plz can u give solution for this logic.... then i can understand well.... i prefer good training for this....

Vivek1982
31st January 2014, 07:46
Thanks alot :)