1 Attachment(s)
QGraphicsWidgets erased slowly
Hi,
I'm working on a QGraphicsScene application in Qt 5,12. In my scene, I have static and dynamic elements. I have two lists of texts on the two side of my screen, as sources and targets. In between them, I have dynamic circle elements which make a trajectory between the source and the target based on the time.
My text item is a QGraphicsWidget in order to be able to stock them in a layout. I overrode the paint function of the QGraphicsWidget in which I call QGraphicsWidget::paint and I also draw a text using QPainter::drawText.
My circle item inherits from QGraphicsEllipseItem and it has two pointers to its source and destination.
By using a QTimer I update the position of my dynamic items so that they are moving from the source to the target.
My problem is that slowly my texts become erased as the circles pass. Please look at the attached screenshot.
I found a workaround to solve this problem by calling update on all of my text item when the timer times out.
Another solution I found is to subclass QgraphicsLayoutItem instead of subclassing the QGraphicsWidget.
Could you please someone explain me why in the first case my texts become erased?
Thanks
Re: QGraphicsWidgets erased slowly
I have noticed that also when I resize my widow my texts are corrected, due to the update event.
I've tried to change the ZValue of my elements because I thought that my texts are not visible due to a circle which masks them but even setting the ZValue does not solve the problem.
Re: QGraphicsWidgets erased slowly
Does somebody has an idea , I still could not figure it out?
Re: QGraphicsWidgets erased slowly
Without seeing your actual code, or a small, self-contained example that shows the problem it is hard to say. Not sure why you are using a custom painter for the text
1 Attachment(s)
Re: QGraphicsWidgets erased slowly
Thank you for your response.
I cannot post my code because it is too large but I wrote a small self-contained example to indicate the problem.
Actually I'm using custom painter for the text because QGraphicsTextItem cannot be inserted in a layout. Hence, first I decided to subclass QGraphicsWidget and override its paint function. With this solution I encountered the problem I've mentioned above. Here is the code:
Code:
class GraphicsTextItem : public QGraphicsWidget
{
public:
: QGraphicsWidget(parent)
, m_Name(name)
, m_Color(50 + (std::rand() % (255 - 50 + 1)), 50 + (std::rand() % (255 - 50 + 1)), 50 + (std::rand() % (255 - 50 + 1)))
{
setMaximumHeight(12);
setMinimumHeight(12);
}
{
painter->setFont(font);
painter->setPen(m_Color);
painter->drawText(0, 0, m_Name);
}
};
class GraphicsTextItem;
{
private:
const GraphicsTextItem* m_Source;
bool m_SourceGood;
public:
GraphicsCircleItem(const GraphicsTextItem* source)
, m_Source(source)
, m_SourceGood(false)
{
setBrush
(QBrush(m_Source
->m_Color
));
setPen
(QPen(m_Source
->m_Color
));
setRect(0, 0, 20, 20);
}
bool isSourcePositionValid() const { return m_Source->pos().x() != 0.0 || m_Source->pos().y() != 0.0; }
void moveAndShow()
{
if(isSourcePositionValid() && m_SourceGood == false)
{
m_SourceGood = true;
setPos(m_Source->scenePos());
show();
return;
}
else
{
if(!m_SourceGood)
hide();
}
if(m_SourceGood)
{
moveBy(1,6);
}
}
};
int main(int argc, char *argv[])
{
MainWindow w;
QGraphicsWidget* layout_widget = new QGraphicsWidget();
QGraphicsLinearLayout* layout = new QGraphicsLinearLayout(Qt::Vertical);
layout_widget->setLayout(layout);
scene->setBackgroundBrush(Qt::black);
scene->addItem(layout_widget);
scene_view->setScene(scene);
scene_view->setSceneRect(0, 0, 1024, 768);
std::vector<GraphicsTextItem*> source_list;
std::vector<GraphicsCircleItem*> message_list;
for(int i = 0; i < 1000; i++)
{
std::string source = std::string("SourceName_") + std::to_string(i);
GraphicsTextItem
* source_item
= new GraphicsTextItem
(nullptr,
QString(source.
c_str()));
layout->addItem(source_item);
source_list.push_back(source_item);
GraphicsCircleItem* message_item = new GraphicsCircleItem(source_item);
scene->addItem(message_item);
message_list.push_back(message_item);
}
timer.callOnTimeout([&]()
{
static uint64_t counter = 0;
if(counter == 500)
{
for(auto& item : message_list)
{
scene->removeItem(item);
delete item;
}
message_list.clear();
for(auto& item : source_list)
{
GraphicsCircleItem* message_item = new GraphicsCircleItem(item);
scene->addItem(message_item);
message_list.push_back(message_item);
}
counter = 0;
}
for(auto& item : message_list)
{
item->moveAndShow();
}
counter++;
});
timer.start(10);
w.setCentralWidget(scene_view);
w.show();
return a.exec();
}
I attach also a photo about the issue with the sample code. As I wrote before I have not encountered this problem if I subclass QGraphicsLayoutItem instead of QGraphicsWidget.
Attachment 13091
I hope the sample code helps.
Re: QGraphicsWidgets erased slowly
Anybody could please advise?