Search code examples
qtqmlqtquick2qgraphicsview

QQuickPaintedItem paint() report error that Timers cannot be stopped from another thread, which seem to cause child threads endless loop?


My code is as follows:

void DrpltGyslPanel::paint(QPainter *painter)
{
    view_->render(painter, boundingRect(), view_->viewport()->rect(), Qt::KeepAspectRatio);
}

DrpltGyslPanel is subclass of QQuickPaintedItem, view_ is instance of QGraphicsView .And I know DrpltGyslPanel::paint is called in QSGRenderThread, but what is this Timer used for? And this also caused child threads endless loop. How can I kill timer exactly? Or one more step for what exactly caused child threads endless loop?

--------------------------------added at 2019/12/19

If the QGraphicsView shows, endless loop won't appear in the Release build and will in the Debug build.


Solution

  • QGraphicsView::addItem will start a timer by default interval(2000ms) at here.QGraphicsView::render will kill timer at here.When killing timer will estimate whether the current thread is thread timer lives to make sure timer usage is in the same thread.So we can not invoke QGraphicsView::render in DrpltGyslPanel::paint from QSGRenderThread. The code is corrected as follows:

    void DrpltGyslPanel::update(const QRect &rect)
    {
        renderPixman = QPixmap(view_->viewport()->rect().size());//renderPixman is member variable
        QPainter painter(&renderPixman);
        view_->render(&painter, boundingRect(), view_->viewport()->rect(), 
        Qt::KeepAspectRatio);
    
        QQuickPaintedItem::update(rect);
    }
    

    And why which will caused child threads endless loop, that is timerEvent alaways triggered.