Error drawing on QWidget output from GUI

I am developing an application in which I want to constantly receive images from a remote host and display them on the screen. for this, I follow this strategy 1) I have a main QWidget object that contains QImage (works fine) 2) Images received from the remote host are painted into a QImage object, this work is performed in a workflow using QPainter. (works fine) 3), but the problem is that the image does not refresh in QWidget, if I do not resize the widget, because the repaint event is fired for QWidget ... Now, if I repaint QWidget from the workflow, it gives an error " QPixmap: it is unsafe to use pixmaps outside the GUI stream ".. and application crashes."

Any help on this?

+3
source share
3 answers

Retrieve the signal from the workflow using QueuedConnection or send the update event ( QPaintEvent) to the widget from the workflow.

//--------------Send Queued signal---------------------
class WorkerThread : public QThread
{
    //...
signals:
    void updateImage();

protected:
    void run()
    {
        // construct QImage
        //...
        emit updateImage();
    }
    //...
};

//...
widgetThatPaintsImage->connect(
    workerThread, 
    SIGNAL(updateImage()), 
    SLOT(update()),
    Qt::QueuedConnection);
//...

//--------------postEvent Example-----------------------
class WorkerThread : public QThread
{
    //...
protected:
    void run()
    {
        //construct image
        if(widgetThatPaintsImage)
        {
            QCoreApplication::postEvent(
                widgetThatPaintsImage, 
                new QPaintEvent(widgetThatPaintsImage->rect()));
        }
        //... 
    }

private:
    QPointer<QWidget> widgetThatPaintsImage;
};

Do not forget to synchronize access to the image.
As an alternative to synchronization, you can also send the image to the gui stream, for example, in the Mandelbrot example .

+9
source

Operations with a graphical interface outside the main thread are not allowed in Qt. All GUI operations should be performed in the main thread in which QApplication lives. Any GUI operation in another thread gives unpredictable results, that is, a failure.

+1

qt, . - -qt- ( ...), 2 3 GUI, ( ).

, 1 QApplication. ( ) , - QApplication.exec().

QThread QApplication exec run(). . . QApplication... - . ( Qapplication ... QWidget GUI... ...)

And for your question, here is the answer. If you want to create only one plugin, you can use QMetaObject :: invokeMethod this code sets pixmap to the label and updates gui.

QImage img;... bool succ = QMetaObject::invokeMethod(mainWin, "DisplaySlot", Qt::QueuedConnection, Q_ARG(QImage, img));

and add a public slot: to your display window

void mainWinClass::DisplaySlot(QImage qim) { (*(ui.label)).setPixmap(QPixmap::fromImage(qim)); (*(ui.label)).update(); }

Hope this helps.

If anyone knows the solution to my problem ... described above (several gui plugins with qt in the host application), write to me.

+1
source

Source: https://habr.com/ru/post/1719070/


All Articles