【问题标题】:QThread doesn't work wellQThread 不能正常工作
【发布时间】:2014-03-17 10:44:16
【问题描述】:

这是 QTread 的子对象... 并在主线程中具体化......

运行时错误如下:

QCoreApplication::sendEvent 中的 ASSERT 失败:“无法将事件发送到 由不同线程拥有的对象。当前线程 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();
}

下面是MainWindow的overridepaintEvent

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

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

    tankPoint->setLeft(200);
}

谁能告诉我为什么?

【问题讨论】:

  • 请至少确保您的问题格式正确。您可以看到(在预览中和发布时)您的问题是什么样的。没有理由有错误格式的代码块。
  • 嗯,谢谢。我会记得这样做..
  • 您从另一个线程访问小部件。那行不通,QWidget 不是线程安全的。您需要从另一个线程发出信号并将其连接到例如小部件的 update() 插槽。

标签: qt qthread


【解决方案1】:

父级(在本例中为您的 MainWindow)位于不同的线程中。根据 Qt 文档

您可以随时使用线程安全函数 QCoreApplication::postEvent() 手动将事件发布到任何线程中的任何对象。事件将由创建对象的线程的事件循环自动分派。 所有线程都支持事件过滤器,但监控对象必须与被监控对象位于同一线程中。同样,QCoreApplication::sendEvent()(与 postEvent() 不同)只能用于将事件分派到位于调用函数的线程中的对象。

因此,作为解决方案,我将提出以下建议:

  • 在 PaintThread 类中定义一个信号
  • 将此信号连接到 QWidget 子类中的 paint() 槽
  • 在 run() 函数中发出它

【讨论】:

  • 此外,在 Qt 中,您不允许在主线程以外的线程中使用任何 GUI 函数(小部件所属的,尤其是绘制方法)。
  • 非常感谢……我已经按照你的建议解决了……而在Qt中两个线程是如何通信的呢?还有其他方法可以解决吗? (除了信号槽)......再次感谢你......
  • 这里有更多关于 qt 线程的文档:developer.qt.nokia.com/doc/qt-4.8/threads-qobject.html
  • 谢谢...明白..o(∩_∩)o
猜你喜欢
  • 1970-01-01
  • 2013-03-30
  • 2010-11-30
  • 2021-10-02
  • 2017-08-06
  • 2013-11-22
  • 1970-01-01
  • 2013-09-10
  • 2017-04-05
相关资源
最近更新 更多