so heres the problem: im creating a GUI app with QT where i need some threads to do some operations at the same time and print the result in a QTextEdit.
#include <QWidget>
#include <QThread>
#include <thread>
#include <cstdlib>
#include <QApplication>
#include <QTextEdit>
#include <QFuture>
#include <QtConcurrent/qtconcurrentrun.h>
#include <iostream>
#include <Windows.h>
using namespace std;
class Win_test : public QWidget
{
private:
QTextEdit *text_panel;
public:
QTextEdit* getPanel();
Win_test();
~Win_test();
};
QTextEdit* Win_test::getPanel() { return text_panel; }
void Thread_test(QTextEdit* where)
{
for( int i = 0 ; i < 90 ; i++ )
{
Sleep(100);
where->append("Hello\n");
}
}
Win_test::Win_test()
{
text_panel = new QTextEdit;
text_panel->setReadOnly(true);
text_panel->setParent(this);
}
Win_test::~Win_test() {}
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
try
{
Win_test *win_test = new Win_test;
QFuture<void> f1 = QtConcurrent::run(Thread_test, win_test->getPanel());
win_test->show();
} catch(exception e)
{
cout << e.what() << endl;
}
return app.exec();
}
When i run this code, sometimes it works and im getting the correct result, and sometimes it crash, when i run it in debug mode it says:
The inferior stopped because it triggered an exception. Stopped in thread 0 by: Exception at 0x7ffdcd89cefa, code: 0xc0000005: read access violation at: 0x0, flags=0x0 (first chance).
i will be very grateful if someone could help me or have encountered this problem. they say that this problem is commonly due to something that is not initialized but im not seing where it can come from.
The problem seems that you're trying to access your GUI from a thread different from the main thread. Only the main thread is allowed to access the GUI:
where->append("Hello\n");
Solution: send a signal from there, connect to a slot somewhere and append from the main thread. This answer is somehow related: QtConcurrent::run emit signal.
Refer to th excellent Qt docs about this topic: https://doc.qt.io/qt-5/thread-basics.html#gui-thread-and-worker-thread. I also suggest reading the entire chapter to find out how good multithreading is in Qt: https://doc.qt.io/qt-5/threads.html. It takes some time to read, but it's worth it.
Multithreading is a difficult topic, you will get subtle bugs also when you know what are doing.
I'm no expert of qt framework but it's easy to spot a big problem in your code: in your main thread you instantiate and show your graphical widget QTextEdit
and run the UI with app.exec();
so the main thread is the GUI thread, where are managed the rendering, position, events of all graphical widget.
Then you pass the pointer of your widget to another thread, so you are accessing the same data from two concurrent threads without a synchronization mechanism: that's undefined behaviour.
The worker thread should pass its result to the main thread (qt provides various mechanisms for this) who can then access and update the widget showing the results.
I think this article could be a good start for you, here's an excerpt:
If two threads have a pointer to the same object, it is possible that both threads will access that object at the same time and this can potentially destroy the object's integrity. It's easy to imagine the many things that can go wrong when two methods of the same object are executed simultaneously.
User contributions licensed under CC BY-SA 3.0