Why isn't my signal and slot working? Button click (signal) is supposed to start a thread (slot).
-
wrote on 10 Apr 2013, 22:20 last edited by
mainwindow.h:
@#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
namespace Ui {
class MainWindow;
}class MainWindow : public QMainWindow
{
Q_OBJECTpublic:
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();
}@
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.
-
@
{
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. -
wrote on 10 Apr 2013, 23:17 last edited by
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?
-
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()));
@ -
wrote on 10 Apr 2013, 23:35 last edited by
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.
-
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 ;)
-
wrote on 11 Apr 2013, 00:15 last edited by
Works perfectly now. Thanks.
-
wrote on 14 Apr 2013, 03:53 last edited by
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. :(
8/8