Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

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 me

    MainWindow.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:

    0_1550073026942_04481009-3c74-4094-b7f1-97fda384b06e-image.png

    what's wrong?

    [Added code tags ~kshegunov]



  • @kshegunov

    Thank you very much!

    I simply replaced

    QMetaObject:invokeMethod(parent,"stopLoop",Qt::QueueConnection);

    on

    parent->stopLoop();

    and the problem is solved!


  • Moderators

    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.



  • @kshegunov

    Thanks for the reply! so how can I disable the pushButton?


  • Moderators

    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.



  • @kshegunov

    Thank you very much!

    I simply replaced

    QMetaObject:invokeMethod(parent,"stopLoop",Qt::QueueConnection);

    on

    parent->stopLoop();

    and the problem is solved!


  • Lifetime Qt Champion

    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.


Log in to reply