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

Qt thread not emiting signal or Main Window not responding to it.



  • Hello, I am new to Qt and I was developing an application where I needed to update an image constantly (or every x seconds), so I created a thread with Qrunnable, as specified in many forum threads, to send a signal to the mainWindow.

    The thread is created and the connection between both the thread and the mainWindow works just fine.

    The problem is that, for any reason, the image is only updated sometimes, and only when I click the button to update it several times whitin a shot period of time.

    I do not know if the problem is the thread, or the problem is the connection or if it is any other problem.

    Thanks in advance for the help, here you can see the code.

    mainwindow.h

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    #include "parameters.h"
    #include <QThreadPool>
    
    QT_BEGIN_NAMESPACE
    namespace Ui { class MainWindow; }
    QT_END_NAMESPACE
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        MainWindow(QWidget *parent = nullptr);
        parameters *param;
        QThreadPool *pool;
        ~MainWindow();
    
    private slots:
        void on_b_new_map_clicked();
    
        void btnaction();
    
        void print_img(char *s);
    
    private:
        Ui::MainWindow *ui;
    };
    #endif // MAINWINDOW_H
    

    mainwindow.cpp

    
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        connect(ui->b_set_parameters,SIGNAL(clicked()),this,SLOT(btnaction())); // creating connections
        pool = QThreadPool::globalInstance();
    }
    
    MainWindow::~MainWindow()
    {
        pool->waitForDone();
        delete ui;
    }
    
    void MainWindow::on_b_new_map_clicked()
    {
        Work work;
        work.setAutoDelete(false);
        connect(&work, &Work::print_img,this, &MainWindow::print_img);
        work.running = true;
        pool->start(&work);
    
    }
    
    void MainWindow::print_img(char *s)
    {
        cv::Mat mat = cv::imread(s);
    
        if(!mat.empty())
        {
            QSize sz = ui->map->frameSize();
            cv::resize(mat, mat, cv::Size(sz.width(), sz.height()));
    
            const uchar *qImage = (const uchar*)mat.data;
    
            QImage img(qImage, mat.cols, mat.rows, mat.step, QImage::Format_RGB888);
    
            ui->map->setPixmap(QPixmap::fromImage(img.rgbSwapped()));
        }
    }
    void MainWindow::btnaction()
    {
        param->show();
        param->setAttribute( Qt::WA_QuitOnClose, false ); //When the main window is closed, the window param will also close.
    }
    

    work.h

    #ifndef WORK_H
    #define WORK_H
    
    #include<QObject>
    #include<QRunnable>
    #include<unistd.h>
    
    
    class Work : public QObject, public QRunnable
    {
        Q_OBJECT
    public:
        bool running;
        void run();
    
    signals:
        void print_img(char *s);
    };
    
    #endif // WORK_H
    

    work.cpp

    #include "work.h"
    
    void Work::run()
    {
        emit print_img("sample.png");
    }
    

  • Lifetime Qt Champion

    @Manu_NaFu said in Qt thread not emiting signal or Main Window not responding to it.:

    void MainWindow::on_b_new_map_clicked()
    {
    Work work;

    C++ Basics - how long do you think does this object live?



  • @Christian-Ehrlicher

    That's true, should I create a work class inside the mainWindow class?



  • @Christian-Ehrlicher I changed it as described in my other comment and now it works perfect. Thanks for the advice, I did not count on that.


  • Lifetime Qt Champion

    @Manu_NaFu Then please mark this topic as solved, thx.


Log in to reply