QWidget::repaint: Recursive repaint detected

  • Hello,

    I use a QWidget in a Qthread and I had to modify the image in a Qlabel of multiple object.
    The problem is when I modify the image inside the Qlabel the update of image works bad.

    I ha to use repaint fonction to force th label to update regulary the display. But most of the time I have this error:

    QWidget::repaint: Recursive repaint detected

    How Can I force a update of the label without create a recursive repaint?

  • Lifetime Qt Champion


    One thing that is wrong here: updating widgets outside the GUI thread is a no go.

    What exactly are you doing ?

  • @SGaist In fact I have a blocking process, this is the reason why I must put a partof my process in a Qthread.
    That Qthread process had to update a list a Qlabel image and display it. The problem if I don't use repaint event the label doesn't refresh dynamically, it waits the last image to update its content.

    So I use repaint and to avoid a recursive repaint error I made that:

        void paintEvent(QPaintEvent *event)
            qDebug() << "GLWidget::paintEvent In";
            qDebug() << "GLWidget::paintEvent Out";

    But it don't seems to work, I still have the same error.

  • Lifetime Qt Champion

    Again: don't do GUI changes to widgets from other threads

    Use signals and slots to update your labels, you may need a class like QSignalMapper. Depending on how you get/generate the images, the Mandelbrot example would likely be useful.

  • Is it possible to have a QSignalMapper like this:

    My QThread send a signal (emit newImage(QImage,int) connect to my object ImageWidget (slot(void newImage(Qimage)) ?

  • Lifetime Qt Champion

    Did you read the class documentation ? It doesn't work like that.

    Anyway, can you describe more precisely your setup ?

  • How should I emit a signal from a QThread?

    Here is the code I use:

    class BGEPreviewWorker : public QObject
        QHash<QString,GLWidget*> hashWidgetView; ///< list of display data
        int iwidth_;            ///< memorise the with of element to process
        int iheight_;           ///< memorise the height of element to process
        cv::Mat dx1_blur1;
        double min,max;
        QHash<QString,GLWidget*> hashWidgetView; ///< list of display data
        BGEPreviewWorker(QObject *parent = NULL);
        /// \brief display function which collct all data in the gpu and display it
        void display();
    public slots:
        void work();
        void askToClosed(QString);
    BGEPreviewWorker::BGEPreviewWorker(QObject *parent):
        hashWidgetView["save_Blur1"]        = new GLWidget(iwidth_,iheight_,GLWidget::BGE_64F,0);
        QHash<QString,GLWidget*>::iterator iter = hashWidgetView.begin();
        for(int i = 0;

    BGEPreviewWorker emit a signal (newImage) to the corresponding GLWirdget.
    Here how I use BGEPreviewWorker:

      BGEPreviewWorker *BGEWork = new BGEPreviewWorker();
       QThread*  BGEThread = new QThread();
        connect(BGEThread, SIGNAL(started()), BGEWork, SLOT(work()) );

  • Moderators

    @Xav12358 It doesn't matter whether you're in another thread or not: emitting signal is always same:

    emit mySignal();

    Just use QueuedConnection when connecting signal and slot.

Log in to reply