我在QGraphicsItem
上有两种类型的QGraphicsView
s,这两种类型中的一种在场景中就像z-index 1的网格,其他的,蚂蚁,在它们之上使用z-index 2.启动程序时,我将所有蚂蚁设置到位置0,0并将它们添加到场景中。但后来我开始通过调用setPos()
从另一个线程移动那些蚂蚁 - 然后我的电脑吃掉了蚂蚁!他们在旧位置上消失了,但没有出现在他们的新位置。新职位在场景中。
以下是Ant
类的代码(继承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);
}
经过一些测试,我发现只要我从Qt事件线程调用setPos
,一切都正常。一旦我在自定义线程中调用它,蚂蚁就会消失。知道如何解决这个问题吗?
答案 0 :(得分:1)
您必须返回主线程才能执行setPos
。正如ddriver所评论的那样,你不应该从一个线程修改GUI(这样做时你通常会收到qDebug
个消息,你在调试器窗口中没有得到任何消息吗?)。
你只需要:
Ant
课程添加新信号(例如signalSetPos( QPoint pos )
)Ant
课程中添加新广告位(例如doSetPos( QPoint pos )
)。此插槽实现只需调用setPos(pos)
。Qt::QueuedConnection
或Qt::BlockingQueuedConnection
(connect
函数的第五个参数连接它们,对于GUI更新,Qt::QueuedConnection
可能更好,因为它不会阻止您的线程) setPos( newPos )
的主题中,只需发出signalSetPos( newPos )
。然后,doSetPos
将在主线程中执行(如果您使用Qt::QueuedConnection
,则会立即执行Qt::BlockingQueuedConnection
。查看此帖子,了解有关从线程发出信号的更多信息: Qt - emit a signal from a c++ thread