3

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?

Bart
  • 19,692
  • 7
  • 68
  • 77
Mr.Tu
  • 2,633
  • 8
  • 31
  • 47
  • Please at least make sure your questions are properly formatted. You can see (in preview and when posted) what your question looks like. There is no reason to have wrongly formatted code blocks. – Bart Jan 26 '12 at 13:44
  • Mmm, Thank you . I will remember doing that .. – Mr.Tu Jan 26 '12 at 14:27
  • You access the widget from another thread. That won't work, QWidget isn't thread-safe. You'll need to emit a signal from the other thread and connect it to e.g. the widget's update() slot. – Frank Osterfeld Jan 26 '12 at 15:04

1 Answers1

3

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
Neox
  • 2,000
  • 13
  • 12
  • And additionally in Qt you are not allowed to use any GUI functions (to which a widget belongs, especially the paint methods) in a thread other than the main thread. – Christian Rau Jan 26 '12 at 13:50
  • Thank you very much... I have solved it according to your propose.. And In Qt How does two thread communicate? there are other ways to solve it? (besides signal-slot)...thank you once more.... – Mr.Tu Jan 26 '12 at 14:32
  • Here is further docu on threading in qt: http://developer.qt.nokia.com/doc/qt-4.8/threads-qobject.html – Neox Jan 26 '12 at 15:07