1

Well after trying everything i know and even by adding

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

To my source i still can't modify the text from other Threads in both QTextEdit and QPlainTextEdit also i am using OpenMP with Qt.

can anyone tell me what is the correct way to modify text from other Threads in QTextEdit and QPlainTextEdit because i didn't manage to find anything about that to help me

Here is my source:

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

I managed to get it work only like this

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

But if i try to set text

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

I get this error

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.

also

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 )
POQDavid
  • 195
  • 1
  • 15

2 Answers2

5

The problem is you are accessing Qt GUI object in a thread other than the main thread.

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

Although QObject is reentrant, the GUI classes, notably QWidget and all its subclasses, are not reentrant. They can only be used from the main thread.

One way around this is to use Qt signals / slots to connect a signal from your worker threads to a slot in your main thread using a QueuedConnection however in your case I do not see this making much sense. Even if you got the signal to work with openmp you will not be able to append strings in a parallel way to QPlainTextEdit that will improve performance.

drescherjm
  • 10,365
  • 5
  • 44
  • 64
0

Well i managed to do it and i think it must be a bit simpler than connecting slots.

in my qt_mainwindow.h i simply added

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

and in my qt_mainwindow.cpp i got this lines

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

Well i tried it as much possible and it didn't failed but i was wondering if i done it correctly

POQDavid
  • 195
  • 1
  • 15
  • @drescherjm so what do you think about this? – POQDavid Jul 04 '15 at 19:15
  • better as for me, but I still think it should be done in qt way ( at least in my opinion ) – Robert Wadowski Jul 04 '15 at 19:21
  • @RobertWadowski so you say this is correct? i can't believe it – POQDavid Jul 04 '15 at 19:24
  • I am saying that is a better but not in qt way. You are using at least meta object system. I wrriten how I would do to load data using thread :) – Robert Wadowski Jul 04 '15 at 19:25
  • @RobertWadowski ok i wonder why app go in to "not responding" state still – POQDavid Jul 04 '15 at 19:27
  • main thread eventloop is blocked. Thread where you loading file has not its own eventloop., QThread has ... – Robert Wadowski Jul 04 '15 at 19:29
  • @RobertWadowski ok idk how to fix this can please help me with this – POQDavid Jul 04 '15 at 19:30
  • We are telling it since beggining. Use qthread class instead, connect signal slots :) – Robert Wadowski Jul 04 '15 at 19:31
  • @RobertWadowski i know but i mean is there a way to fix it using this way? – POQDavid Jul 04 '15 at 19:33
  • @RobertWadowski ok i will also work on connect signal slots but i really wanted to be like only OpenMP not involving QThread – POQDavid Jul 04 '15 at 19:40
  • @RobertWadowski this connect sinnal slots involves that i make a QThread and run my OpenMP thread in there right? – POQDavid Jul 04 '15 at 19:50
  • If you are using openmp with 1 thread is it even creating a thread at all? – drescherjm Jul 04 '15 at 23:36
  • Also for the case of creating QThreads I say it will take longer with additional threads than just executing in the main thread for the code you posted. marshalling the data has a time cost + the main thread needs to add the strings to the widget anyways. See the description of Queued Connections in this answer: http://stackoverflow.com/a/10839370/487892 – drescherjm Jul 04 '15 at 23:40
  • @drescherjm I think it makes the thread since it was crashing and ok so you guys are saying that i don't use OpenMP at all? – POQDavid Jul 05 '15 at 08:14