Why isn't my signal and slot working? Button click (signal) is supposed to start a thread (slot).



  • mainwindow.h:

    @#ifndef MAINWINDOW_H
    #define MAINWINDOW_H

    #include <QMainWindow>

    namespace Ui {
    class MainWindow;
    }

    class MainWindow : public QMainWindow
    {
    Q_OBJECT

    public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

    private slots:

    private:
    Ui::MainWindow *ui;
    };

    #endif // MAINWINDOW_H@

    myobject.h:

    @#ifndef MYOBJECT_H
    #define MYOBJECT_H

    #include <QtCore>

    class MyObject : public QObject
    {
    Q_OBJECT
    public:
    explicit MyObject(QObject *parent = 0);

    signals:

    public slots:
    void doWork();

    };

    #endif // MYOBJECT_H@

    main.cpp:

    @#include "mainwindow.h"
    #include <QApplication>

    int main(int argc, char *argv[])
    {
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec&#40;&#41;;
    

    }@

    mainwindow.cpp:

    @#include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include "myobject.h"

    MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    ui->setupUi(this);

    QThread cThread;
    MyObject cObject;
    cObject.moveToThread(&cThread);
    
    QObject::connect(ui->pushButton, SIGNAL(clicked()), &cThread, SLOT(start()));
    QObject::connect(&cThread, SIGNAL(started()), &cObject, SLOT(doWork()));
    

    }

    MainWindow::~MainWindow()
    {
    delete ui;
    }@

    myobject.app:

    @#include "myobject.h"
    #include <QDebug>

    MyObject::MyObject(QObject *parent) :
    QObject(parent)
    {
    }

    void MyObject::doWork()
    {
    qDebug() << "1";
    }@

    I'm quite stumped. No errors. No output (should be gettting "1" from qDebug when clicking on the button). :|

    I can't see what's wrong.


  • Moderators

    @
    {
    ui->setupUi(this);

    QThread cThread; //cThread is a local stack variable
    MyObject cObject; //cObject is a local stack variable
    cObject.moveToThread(&cThread);
    
    QObject::connect(ui->pushButton, SIGNAL(clicked()), &cThread, SLOT(start()));
    QObject::connect(&cThread, SIGNAL(started()), &cObject, SLOT(doWork()));
    

    } //here both cThread and cObject go out of scope, and thus are destroyed and disconnected from anything
    @
    You should create the thread and your object on the heap with a new keyword.



  • Solution:

    @mainwindow.cpp:

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include "myobject.h"

    MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    ui->setupUi(this);

    QThread *cThread = new QThread();
    MyObject *cObject = new MyObject();
    cObject->moveToThread(cThread);
    
    QObject::connect(ui->pushButton, SIGNAL(clicked()), cThread, SLOT(start()));
    QObject::connect(cThread, SIGNAL(started()), cObject, SLOT(doWork()));
    

    }

    MainWindow::~MainWindow()
    {
    delete ui;
    }@

    Wow. Thanks man! I really appreciate it.

    But now how do I prevent a memory leak? If they're on the heap, then doesn't that mean that I have to free the memory or something?


  • Moderators

    Yup, you should delete it somewhere(lika in a destructor), or... do it the Qt way :)
    QObjects (like your thread) taka a parent parameter in their constructor. Set this to any other QObject (eg. your window) and it will be automagically deleted when the parent is.

    Alternatively, if you don't need the thread after its completion, you can do this:
    @
    MyObject *cObject = new MyObject(cThread); //make the object be destroyed with the thread
    connect(cThread, SIGNAL(finished()), cThread, SLOT(deleteLater()));
    @



  • Thanks. Just would like to make sure that this is correct (this is the first way that you mentioned i.e. using parents):

    @QThread *cThread = new QThread(QMainWindow);
    MyObject *cObject = new MyObject(cThread);@

    Edit: Getting mainwindow.cpp:11: error: C2275: 'QMainWindow' : illegal use of this type as an expression

    Hmm... Not sure what I did wrong. :|

    Edit 2: Changed it to this and it's working now:

    @QThread *cThread = new QThread(this);
    MyObject *cObject = new MyObject(cThread);@

    Edit 3: Argh, now I'm getting this during runtime: QObject::moveToThread: Cannot move objects with a parent.

    Edit 4: Would it be ok if there are memory leaks? It's a small program anyways, so I don't want to waste your time.


  • Moderators

    Ah, sorry. I should be sleeping a long time ago :P

    This should work:
    @
    QThread *cThread = new QThread(this);
    MyObject *cObject = new MyObject();
    cObject->moveToThread(cThread);

    QObject::connect(ui->pushButton, SIGNAL(clicked()), cThread, SLOT(start()));
    QObject::connect(cThread, SIGNAL(started()), cObject, SLOT(doWork()));
    
    QObject::connect(cThread, SIGNAL(finished()), cThread, SLOT(deleteLater()));
    QObject::connect(cThread, SIGNAL(finished()), cObject, SLOT(deleteLater()));
    

    @

    Or instead of that last connect you can manually schedule cObject for destruction in your doWork slot by calling deleteLater() there.

    Just remember that you should end your thread at some point otherwise it will spin around till the end of program and you will get a runtime warning: "QThread: Destroyed while thread is still running" and there will be no finished() signal so things won't get destroyed.
    You can do this for example in the doWork() slot by calling QThread::currentThread()->quit();

    As for "small memory leaks" - NO :) You will burn in programmers hell for saying such things ;)



  • Works perfectly now. Thanks.



  • https://mega.co.nz/#!xUMiSRYC!Y8Sxz2fEFb6yEIrnKiGx9n2zeK4YTUwUrCByaAkcOPI

    So I've worked on the project a bit more and I'm experiencing a problem with QThread::currentThread()->quit();

    If you open up my myobject.cpp and go to line 13, the quit() call is supposed to exit. But it seems the quit() call isn't working and it just skips it. Can't see the problem. :(


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.