Reputation: 8371
I have two types of QGraphicsItem
s on a QGraphicsView
, one of those two types are in the scene like grid with z-index 1, the other ones, ants, are on top of them with z-index 2. When starting the program, I set all ants to position 0,0 and add them to the scene. But then I start moving those ants from another Thread by calling setPos()
on them - and then my computer eats the ants! They disapper at their old position, but don't appear at their new position. The new position is inside the scene.
Here is the code of Ant
class (that inherits QGraphicsItem
):
#include "ant.h"
#include "constants.h"
#include <QPainter>
Ant::Ant()
{
setZValue(2);
}
QRectF Ant::boundingRect() const
{
return QRect(QPoint(0,0), G_FIELD_RECT_SIZE);
}
void Ant::paint(QPainter *painter, const QStyleOptionGraphicsItem *item, QWidget *widget)
{
Q_UNUSED(item)
Q_UNUSED(widget)
QBrush b = painter->brush();
if (food())
painter->setBrush(Qt::blue);
else
painter->setBrush(Qt::black);
painter->drawEllipse(2,3, G_FIELD_RECT_WIDTH - 4, G_FIELD_RECT_HEIGHT - 6);
painter->setBrush(b);
}
After a bit more testing, I found out that everything is working as long as I call setPos
from the Qt Event Thread. As soon as I call it in an custom thread, the ants disappear. Any idea how I can solve this?
Upvotes: 2
Views: 761
Reputation: 21514
You must go back to the main thread to do the setPos
. As commented by ddriver, you should not modify GUI from a thread (you usually get qDebug
messages when doing so, didn't you get any in your debugger window?).
You just need to:
Ant
class (like signalSetPos( QPoint pos )
)Ant
class (like doSetPos( QPoint pos )
). This slot implementation simply calls setPos(pos)
.Qt::QueuedConnection
or Qt::BlockingQueuedConnection
(fifth parameter of the connect
function, for GUI update, Qt::QueuedConnection
may be preferable because it won't block your thread).setPos( newPos )
, just do emit signalSetPos( newPos )
. Then, doSetPos
will be executed (later if you used Qt::QueuedConnection
, right away if you used Qt::BlockingQueuedConnection
) from the main thread.Check this post for more information about emitting signals from threads: Qt - emit a signal from a c++ thread
Upvotes: 2