Am I correct in thinking that the QGraphics* classes are not thread-safe? I am porting an old app to Qt and in the process attempting to make it multi-threaded too. I looked at the update code and I see no locks whatsoever.
I started off right, all my processing is done in a set of worker threads so that the GUI does not have to block. But as soon as I come to display my visual representation the whole thing falls down like a pack of cards as the update code attempts to read from the buffer the other thread is writing to.
Here is my test case:
- Create a bunch of ellipse objects
- Create a thread and pass it the scene pointer
- In a loop modify any setting on any object in the scene.
Test function:
bool CBasicDocument::Update( float fTimeStep )
{
const QList<QGraphicsItem*> tObjects = items();
for( QList<QGraphicsItem*>::const_iterator tIter = tObjects.constBegin();
tIter != tObjects.constEnd();
++tIter )
{
QGraphicsEllipseItem* pElipse = (QGraphicsEllipseItem*)(*tIter);
if( pElipse )
{
pElipse->setPen( QPen( QColor( (int)(255.0f * sinf( fTimeStep )), (int)(255.0f * cosf( fTimeStep )), (int)(255.0f * sinf( fTimeStep )) ) ) );
}
}
return true;
}
I have been thinking about ways I can fix this and none of them are particularly pretty.
Ideally what I want to happen is when I change a setting on an object it is buffered until the next render call, but for the time being I'll settle with it not crashing!
At the moment I have four options:
Double buffer the whole scene maintaining two scene graphs in lockstep (one rendering, one updating). This is how our multithreaded game engine works. This is horrible here though because it will require double the CPU time and double the memory. Not to mention the logistics of maintaining both scene graphs.
Modify QGraphics* to be thread safe as above. This is probably the most practical approach but it will be a lot of work to get it done.
Push modifications to the scene into a queue and process them from the main thread.
Throw multithreading to the wind for the time being and just let my app stall when the document updates. (Not pretty given the data size for some documents)
None of them are particularly appealing and all require a massive amount of work.
Does anybody have any ideas or attempted multithreading QGraphicsScene before?
Cheers