ASSERT failure in QCoreApplication::sendEvent: 'Cannot send events to objects owened by a different thread
-
hello to the whole community Qt Forum,
I need a help I can not understand the problem that is reporting in my code .. as the codes of my application is too long .. I bring here a similar code and I know that the error comes from there .. I can you tell what's wrong? thank you very much to those who will help meMainWindow.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include "afxwin.h" #include <iostream> #include <thread> #include <QDebug> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = nullptr); ~MainWindow(); static void MainThread(LPVOID lp); public slots: void stopLoop(); private: Ui::MainWindow *ui; std::thread t; }; #endif // MAINWINDOW_H
MainWindow.cpp
#include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); t = std::thread(MainThread,(void*)this); } MainWindow::~MainWindow() { delete ui; } void MainWindow::MainThread(LPVOID lp) { MainWindow *parent = (MainWindow*)lp; qDebug()<<"Hello Concurrent World\n"; parent->stopLoop(); } void MainWindow::stopLoop() { t.detach(); ui->pushButton->setEnabled(false); }
main.cpp
#include "mainwindow.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); }
the error that brings me back is:
what's wrong?
[Added code tags ~kshegunov]
-
This:
ui->pushButton->setEnabled(false);
is a race condition. You mustn't touch any UI object from a thread different than the GUI one. As a matter of fact, you shouldn't execute methods of GUI classes in different threads, that's basically asking for trouble.
-
Start reading here. There are also examples throughout the documentation how threads are to interact with the GUI (and in the forum as well).
In a nutshell you have to emit a signal that's connected to a slot, which in turn is going to disable the button. Before doing that, however, you need a
QObject
that's going to emit it, and which is living in the worker thread.PS. Here's some skeleton code how to spin a thread Qt-style.
-
Hi,
Except that it's the wrong thing to do. You are currently just lucky it works. As already stated, don't modify GUI elements from another thread.Sorry, I misunderstood what you wrote. invokeMethod is a solution.
However, you should still consider clean separation between UI updates and thread processing.