QThread doesn't work well

2019-02-18 15:57发布

问题:

this's the QTread's subObject... and concrete it in main Thread....

the Runtime error as follow:

ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread 176f0a8. Receiver '' (of type 'MainWindow') was created in thread 3976a0", file c:\ndk_buildrepos\qt-desktop\src\corelib\kernel\qcoreapplication.cpp, line 405 Invalid parameter passed to C runtime function. Invalid parameter passed to C runtime function.

class PaintThread : public QThread {

private:
    QWidget* parent;

public:
    ~PaintThread() {}

    PaintThread(QWidget* parent = 0) {
        this->parent = parent;
    }

    void run() {
        while (1) {
            this->msleep(5000);
            parent->repaint();
        }
        this->exec();
    }
};

this's the MainFrame 's constructor :

MainWindow::MainWindow(QWidget *parent) :
QWidget(parent)
{
tankPoint = new QRect(50, 50, 30, 30);

this->show();

PaintThread * pt = new PaintThread(this);
pt->start();
}

the follow is the override paintEvent for MainWindow

void paintEvent(QPaintEvent*) {
    QPainter  p(this);

    p.setPen(Qt::red);
    p.setBrush(Qt::red);
    p.drawEllipse(*tankPoint);

    tankPoint->setLeft(200);
}

Can anyone tell me why?

回答1:

The parent (in this case your MainWindow) lives in a different thread. According to Qt documentation

You can manually post events to any object in any thread at any time using the thread-safe function QCoreApplication::postEvent(). The events will automatically be dispatched by the event loop of the thread where the object was created. Event filters are supported in all threads, with the restriction that the monitoring object must live in the same thread as the monitored object. Similarly, QCoreApplication::sendEvent() (unlike postEvent()) can only be used to dispatch events to objects living in the thread from which the function is called.

So as a solution I would propose the following:

  • Define a signal in your PaintThread class
  • connect this signal to the paint() slot in QWidget subclass
  • Emit it in the run() function


标签: qt qthread