QThread работает плохо

это подобъект QTread... и конкретизируйте его в основном потоке....

ошибка времени выполнения следующим образом:

Ошибка ASSERT в QCoreApplication::sendEvent: «Невозможно отправить события объектам, принадлежащим другому потоку. Текущий поток 176f0a8. Получатель» (типа «MainWindow») был создан в потоке 3976a0», файл c:\ndk_buildrepos\qt-desktop \src\corelib\kernel\qcoreapplication.cpp, строка 405 Недопустимый параметр, переданный в функцию времени выполнения C. В функцию времени выполнения C передан недопустимый параметр.

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();
    }
};

это конструктор MainFrame:

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

this->show();

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

далее следует переопределение paintEvent для MainWindow.

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

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

    tankPoint->setLeft(200);
}

Кто-нибудь может сказать мне, почему?


person Mr.Tu    schedule 26.01.2012    source источник
comment
Пожалуйста, хотя бы убедитесь, что ваши вопросы правильно отформатированы. Вы можете увидеть (в предварительном просмотре и при публикации), как выглядит ваш вопрос. Нет причин иметь неправильно отформатированные блоки кода.   -  person Bart    schedule 26.01.2012
comment
Ммм, Спасибо. Я буду помнить, что делал это..   -  person Mr.Tu    schedule 26.01.2012
comment
Вы получаете доступ к виджету из другого потока. Это не сработает, QWidget не является потокобезопасным. Вам нужно будет излучать сигнал из другого потока и подключать его, например. слот update() виджета.   -  person Frank Osterfeld    schedule 26.01.2012


Ответы (1)


Родитель (в данном случае ваш MainWindow) живет в другом потоке. Согласно документации Qt

Вы можете вручную отправлять события любому объекту в любом потоке в любое время, используя потокобезопасную функцию QCoreApplication::postEvent(). События будут автоматически отправлены циклом событий потока, в котором был создан объект. Фильтры событий поддерживаются во всех потоках с тем ограничением, что объект мониторинга должен находиться в том же потоке, что и отслеживаемый объект. Точно так же QCoreApplication::sendEvent() (в отличие от postEvent()) может использоваться только для отправки событий объектам, живущим в потоке, из которого вызывается функция.

Поэтому в качестве решения я бы предложил следующее:

  • Определите сигнал в вашем классе PaintThread
  • подключите этот сигнал к слоту paint() в подклассе QWidget
  • Выпустите его в функции run()
person Neox    schedule 26.01.2012
comment
Кроме того, в Qt вам не разрешено использовать какие-либо функции графического интерфейса (к которым принадлежит виджет, особенно методы рисования) в потоке, отличном от основного потока. - person Christian Rau; 26.01.2012
comment
Большое спасибо ... Я решил это в соответствии с вашим предложением .. И в Qt Как взаимодействуют два потока? есть другие пути решения? (кроме сигнального слота)...еще раз спасибо.... - person Mr.Tu; 26.01.2012
comment
Вот еще документ по многопоточности в qt: developer.qt.nokia .com/doc/qt-4.8/threads-qobject.html - person Neox; 26.01.2012
comment
Спасибо... понял.. о(∩_∩)о - person Mr.Tu; 26.01.2012