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

    Hi,

    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";
            if(!paintingActive())
                QWidget::paintEvent(event);
            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
    
        Q_OBJECT
        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
    public:
    
        BGEPreviewWorker(QObject *parent = NULL);
        ~BGEPreviewWorker();
    
        ///
        /// \brief display function which collct all data in the gpu and display it
        ///
        void display();
    
    
    
    public slots:
        void work();
        void askToClosed(QString);
    
    signals:
    };
    
    
    BGEPreviewWorker::BGEPreviewWorker(QObject *parent):
        QObject(parent),
        iwidth_(1920),
        iheight_(1080),
        bIsRunning_(false),
        bIsInitialised_(false)
    {
    
    
    
    
        dx1_blur1.create(iheight_,iwidth_,CV_64F);
    
        hashWidgetView["save_Blur1"]        = new GLWidget(iwidth_,iheight_,GLWidget::BGE_64F,0);
    
    
    
        QHash<QString,GLWidget*>::iterator iter = hashWidgetView.begin();
        for(int i = 0;
            i<hashWidgetView.size();
            i++)
        {
            connect(this,SIGNAL(newImage(ImageUpdater)),((iter+i)).value(),SLOT(newImage(ImageUpdater)));
            
    
    
            (iter+i).value()->show()
    
        }
    
    }
    

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

      BGEPreviewWorker *BGEWork = new BGEPreviewWorker();
       QThread*  BGEThread = new QThread();
        BGEWork->moveToThread(BGEThread);
    
        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
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.