PDA

View Full Version : How to render QGraphicsItems onto a QGraphicsScene properly



jshafferman
24th April 2014, 16:59
I have a custom QGraphicsScene where I reimplement the drawbackground function and draw using opengl. I am rendering everything as expected in drawbackground. However when I add a QGraphicsItem to the scene I seem to be having difficulty getting the items to render appropriately. I am able to render a QGraphicsSimpleTextItem fine, however not so much with a QGraphicsPixmapItem. If I try to just add the QGraphicsPixmapItem nothing appears on the screen, however if I add both the QGraphicsSimpleTextItem and QGraphicsPixmapItem both render fine. I have no idea why this is happening, so I am hoping by taking a look at my main function anyone might be able to steer me straight. This is just a small program designed to teach myself how to properly add items to a QGraphicsScene.



#include "glgraphicsscene.h"

#include <QApplication>
#include <QGraphicsView>
#include <QGraphicsSimpleTextItem>
#include <QGraphicsPixmapItem>
#include <QPixmap>
#include <QDebug>

int main(int argc, char *argv[])
{
QApplication app(argc, argv);

GLGraphicsScene* glScene = new GLGraphicsScene;

QGraphicsSimpleTextItem textItem("Hello QGraphicsItem!");
textItem.setBrush(Qt::black);

QPixmap pixmap;

qDebug() << pixmap.load("../Bounce/graphicsview-pixmapitem.png");
qDebug() << pixmap.isNull();
qDebug() << pixmap.width();
qDebug() << pixmap.height();
qDebug() << pixmap.hasAlpha();

QGraphicsPixmapItem* gpixmap = new QGraphicsPixmapItem(pixmap);
gpixmap->setVisible(true);

// this works fine all the time
glScene->addItem(&textItem);

// this won't render unless line above is done first
glScene->addItem(gpixmap);

// just to find out if items are being added for my benefit
for(int i = 0; i < glScene->items().size(); i++)
{
qDebug() << glScene->items().at(i);
}

QGraphicsView view;
view.setViewport(new QGLWidget(QGLFormat(QGL::DoubleBuffer | QGL::Rgba)));
view.setViewportUpdateMode(QGraphicsView::FullView portUpdate);
view.setScene(glScene);
view.show();

app.exec();
}


Any ideas, I haven't found anything on the internet to tell me why this won't work. Any help is greatly appreciated!

jshafferman
25th April 2014, 22:01
Just an FYI, if I strictly just add the QPixmap to the scene and the view is a regular QWidget. It renders fine... I have looked through every bit of information I can and I have yet to see anything that relates to my current problem. If anyone needs more implementation shown that is fine with me, and I can post the drawBackground call if necessary. Thanks for any help because I am completely lost :(

jshafferman
26th April 2014, 14:58
One more additional FYI, I put plain QGraphicsScene added a QPixmap/QGraphicsPixmapItem to it, created a QGraphicsView and set its viewport to a QGLWidget and the Pixmap would not render on the screen. This is leading me to believe that there is sometype of bug in Qt. Maybe it can't be directly applied, maybe it has to be a subclassed QGraphicsItem and in the paint function I just make the pixmap image? I am not sure just trying to find out what exactly has to happen in order for this work without sometype of silly hack (adding a QGraphicsSimpleText item first or something silly like that). Thanks again for any help. Oh and I am using Qt 4.8.7, I am going to see if it is fixed with Qt 5.2

Added after 8 minutes:

Quick side note, this appears to be fixed in 5.2, however at my office we use 4.8.7, so I am still curious if this is something that is documented somewhere.

d_stranz
27th April 2014, 01:23
One problem with your code, which in this case probably works but simply by accident, is that you are creating your text item on the stack. It works here because the main() method doesn't exit until the app does, so the text item stays in scope. However, if you do this same thing anywhere else in a method that returns, your text item will be destroyed (and thus removed from the scene) as soon as the method exits. That's a bug waiting to happen.

On the other hand, you allocate the scene on the heap, the pixmap item on the heap, but the pixmap itself on the stack. It is very inconsistent. The first fix I would make is to allocate everything on the heap using new (except maybe the pixmap itself, since the pixmap item makes a copy) and see if there's a change in behavior.

You also haven't given any graphics item a position, nor have you set a size for the scene or view. So who knows if this reliance on default behavior is what is causing the problem?

jshafferman
28th April 2014, 14:55
Yes I agree I am doing things with the stack and heap that you normally wouldn't do (however as you mentioned it is in the main function so shouldn't be an issue). I was actually 'trying' to break it at first and then I couldn't get it to appear no matter what, so I decided to show you the code as is. I have removed any stack implementation and went strictly to heap calls and I wasn't able to see any difference. I also have set the view's height/width to 600x600 (arbitrary nothing particular) and moved the pixmap to pos(10,10) which should show up since my scene is 600x600 and my image is 200x200. After those few changes no behavior change at all. I also tried creating a simple qgraphicsitem from the example given in the QGraphicsItem documentation and could not get it to appear using a QGLWidget however it appears just fine when using a normal QWidget. I thought maybe for some reason in Qt 4.8 you have to override the paint function or something silly like that but that isn't true. I don't know if this is a bug in Qt 4.8 or not still trying to find out what is wrong with QGraphicsView/Scene with QGLWidget. If anyone has any information that would be great and thanks d_stranz for your comments, any other ideas? I will post any findings on have on this post. Thanks for any help!

jshafferman
30th April 2014, 15:30
It appears to not be an issue with Qt, but rather an issue with the environment that we build in. I was able to get rendering fine with a native Linux machine however with the version of VM player that we currently have there appears to be problems with QGraphicsScene/QGraphicsView rendering properly. We are using a pretty old VM and I am guessing that version's 3D acceleration doesn't actually work properly. I am going to find out if it is possible that the version of ubuntu we run at work also has something to do with it. If this sparks any ideas, please let me know. Thanks!

jshafferman
1st May 2014, 02:45
I know I am posting a lot to myself but I would like people who view this thread to know the problems I am experiencing. So I have the most up to date VM player, the newest Ubuntu 64-bit OS and I installed and used qt 5.2.1 and everything rendered perfect. When I installed 4.8.6 and ran the same code I wasn't able to see the QPixmap render on the screen. However I was able at work to run it on a native Ubuntu system and it rendered fine, so I still believe it has something to do with VM/Ubuntu but it is still interesting to note that 4.8.6 doesn't render the same as 5.2 in the same environment.