Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Why isn't my signal and slot working? Button click (signal) is supposed to start a thread (slot).

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

Scheduled Pinned Locked Moved General and Desktop
8 Posts 2 Posters 4.1k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T Offline
    T Offline
    tahayassen
    wrote on last edited by
    #1

    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.

    1 Reply Last reply
    0
    • Chris KawaC Offline
      Chris KawaC Offline
      Chris Kawa
      Lifetime Qt Champion
      wrote on last edited by
      #2

      @
      {
      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.

      1 Reply Last reply
      0
      • T Offline
        T Offline
        tahayassen
        wrote on last edited by
        #3

        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?

        1 Reply Last reply
        0
        • Chris KawaC Offline
          Chris KawaC Offline
          Chris Kawa
          Lifetime Qt Champion
          wrote on last edited by
          #4

          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()));
          @

          1 Reply Last reply
          0
          • T Offline
            T Offline
            tahayassen
            wrote on last edited by
            #5

            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.

            1 Reply Last reply
            0
            • Chris KawaC Offline
              Chris KawaC Offline
              Chris Kawa
              Lifetime Qt Champion
              wrote on last edited by
              #6

              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 ;)

              1 Reply Last reply
              0
              • T Offline
                T Offline
                tahayassen
                wrote on last edited by
                #7

                Works perfectly now. Thanks.

                1 Reply Last reply
                0
                • T Offline
                  T Offline
                  tahayassen
                  wrote on last edited by
                  #8

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

                  1 Reply Last reply
                  0

                  • Login

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved