OpenMP,QTextEdit和QPlainTextEdit

时间:2015-07-04 13:51:40

标签: c++ multithreading qt openmp

在尝试了解我所知道的一切之后,甚至添加

QT_MainWindow::QT_MainWindow(QWidget *parent) :QMainWindow(parent), ui(new Ui::QT_MainWindow)
{
    ui->setupUi(this);
    qRegisterMetaType<QTextCursor>("QTextCursor");
    qRegisterMetaType<QTextBlock>("QTextBlock");
}

在我的源代码中,我仍然无法修改QTextEdit和QPlainTextEdit中其他线程的文本,我也在使用OpenMP和Qt。

任何人都可以告诉我在QTextEdit和QPlainTextEdit中修改其他Threads文本的正确方法是什么,因为我没有设法找到任何可以帮助我的内容

这是我的来源:

void QT_MainWindow::Load()
{
    ui->QT_PlainTextEdit->setPlainText("");

    std::ifstream file("File.txt");
    std::string line;
    #pragma omp parallel
    {
    while ( std::getline(file, line) )

    ui->QT_PlainTextEdit->appendPlainText( QString::fromStdString(line));

    file.close();
    }
}

我设法让它像这样工作

void QT_MainWindow::Load()
{
    omp_set_dynamic(0);
    omp_set_nested(3);
    #pragma omp parallel num_threads(3)
    {
      ui->QT_PlainTextEdit->setPlainText("");
    }
}

但如果我尝试设置文字

void QT_MainWindow::Load()
{
    omp_set_dynamic(0);
    omp_set_nested(3);
    #pragma omp parallel num_threads(3)
    {
      ui->QT_PlainTextEdit->setPlainText("TEST");
    }
}

我收到此错误

QObject: Cannot create children for a parent that is in a different thread.
(Parent is QTextDocument(0x3bbc758), parent's thread is QThread(0x3bd140), current thread is QThread(0x3bbcb68)
The program has unexpectedly finished.

QObject: Cannot create children for a parent that is in a different thread.
(Parent is QTextDocument(0x465bfc0), parent's thread is QThread(0x3f3ad60), current thread is QThread(0x466d450)QObject: Cannot create children for a parent that is in a different thread.
(Parent is QTextDocument(0x465bfc0), parent's thread is QThread(0x3f3ad60), current thread is QThread(0x46eebe0)HEAP[app.exe]: 
Invalid address specified to RtlFreeHeap( 00000000023F0000, 0000000003F3DC40 )

2 个答案:

答案 0 :(得分:5)

问题是您正在主线程以外的线程中访问Qt GUI对象。

来自http://doc.qt.io/qt-4.8/threads-qobject.html

  

虽然QObject是可重入的,但是GUI类,尤其是QWidget和   它的所有子类都不是可重入的。它们只能用于   主线。

解决此问题的一种方法是使用Qt信号/插槽使用QueuedConnection将工作线程中的信号连接到主线程中的插槽,但在您的情况下,我认为这没有多大意义。即使您获得了使用openmp的信号,您也无法以与QPlainTextEdit并行的方式追加字符串,从而提高性能。

答案 1 :(得分:0)

我设法做到了,我认为它必须比连接插槽更简单。

在我的qt_mainwindow.h中,我只是添加了

public slots:
    void QT_PlainTextEdit_appendPlainText(QString line);
    void QT_PlainTextEdit_SetText(QString line);

在我的qt_mainwindow.cpp中我得到了这一行

void QT_MainWindow::QT_PlainTextEdit_appendPlainText(QString line)
{
    ui->QT_PlainTextEdit->appendPlainText(line);
}

void QT_MainWindow::QT_PlainTextEdit_SetText(QString line)
{
    ui->QT_PlainTextEdit->setPlainText(line);
}

void QT_MainWindow::Load()
{
    #pragma omp parallel num_threads(1)
    {
        std::ifstream file("file.txt");
        std::string line;

        while ( std::getline(file, line) )
            QMetaObject::invokeMethod(this,"QT_PlainTextEdit_appendPlainText",Qt::QueuedConnection,Q_ARG(QString,QString::fromStdString(line)));
        file.close();
    }
}

我尽可能地尝试了它并没有失败,但我想知道我是否正确完成了