LINUX.ORG.RU

Qt threads


0

1

Как с помощью Qt thread-ов запустить функцию своево класса как поток? Класс не наследован от QThread.


class Foo : public QObject
{
    Q_OBJECT
    // lots of blah...

public Q_SLOTS:
    void start();
};

int main() {
    QThread* thread = new QThread;
    Foo* foo = new Foo;

    foo->moveToThread(thread);

    thread->start();

    return 0;
}

если ничего не попутал, то как то так

shty ★★★★★
()
Ответ на: комментарий от anonymous

думаю что да, но сильно размышлять времени не было, в моём коде для чего-то использовался (забыл уже для чего) :)

shty ★★★★★
()
Ответ на: комментарий от shty

Сделал так как вы сказали. вот код

#include <QtGui>
#include <QThread>

class Foo : public QObject {
        Q_OBJECT;

public Q_SLOTS:
        void start() {qDebug() << "hello\n";}
};      

int main(int argc, char **argv)
{       
        QApplication app(argc,argv);
        QThread* thread = new QThread;
        Foo* foo = new Foo;
        
//      f->moveToThread(t);
//      t->start();
        return app.exec();
}       

Выдает ошибку на «Foo* foo = new Foo;». Как я понял это связанно с неопределенными виртуальными функциями. Какие функции я должен определить чтобы заработало?

gDendy
() автор топика
Ответ на: комментарий от gDendy

>связанно с неопределенными виртуальными функциями. Какие функции я должен определить чтобы заработало?

Компилятор что конкретно говорит?

slackwarrior ★★★★★
()
Ответ на: комментарий от slackwarrior

g++ -Wl,-O1 -o th main.o -L/usr/lib -lQtGui -lQtCore -lpthread

main.o: In function `main':

main.cpp:(.text+0x75): undefined reference to `vtable for Foo'

collect2: ld returned 1 exit status

make: *** [th] Error 1

gDendy
() автор топика
Ответ на: комментарий от gDendy

Добавить в конец файла:

#include "moc_main.cpp"

И сделать:

$ moc main.cpp > moc_main.cpp

Либо вынести объявление класса Foo в отдельный заголовочный файл.

rival ★★
()
Ответ на: комментарий от rival

Ошибку больше не дает, все нормально компилируется и работает, но поток не запускаеться. Что я не правильно сделал?? вот код main.cpp

#include "class.h"

int main(int argc, char **argv)
{
        QApplication app(argc,argv);
        QThread* thread = new QThread;
        Foo* foo = new Foo;

        foo->moveToThread(thread);
        thread->start();
        return app.exec();
}
class.h
#include <QtGui>
#include <QThread>

class Foo : public QObject {
        Q_OBJECT
                public Q_SLOTS:
                void start() {qDebug() << "hello\n";}
};

gDendy
() автор топика
Ответ на: комментарий от gDendy

Он запускается, причем даже с event loop'ом в новых версиях Qt, но ничего не делает. Ты наверное думаешь, что за тебя кто-то вызовет слот Foo::start, а зря, тебе нужно вызывать его самому.

Вот тебе полный пример:

#include <QtGui>
#include <QThread>

class Foo : public QObject {
  Q_OBJECT;

  public Q_SLOTS:
    void hello() { qDebug() << "hello from" << thread(); }
};

int main(int argc, char **argv)
{
  QApplication app(argc, argv);
  QThread* thread = new QThread;
  Foo* foo = new Foo;

  foo->moveToThread(thread);
  thread->start();

  // Исключительно в показательных целях. 
  // В реальном приложении нужно связать слот с каким-нибудь сигналом.
  QMetaObject::invokeMethod(foo, "hello", Qt::AutoConnection);

  qDebug() << "main thread" << app.thread();

  return app.exec();
}

#include "moc_main.cpp"

rival ★★
()
Ответ на: комментарий от gDendy

Что-то вы тут все не то делаете. Этот код просто переносит Ваш QObject-класс в эвент луп нового потока, но ничего не запускает.

Нужно ещё как-то вызвать этот слот в Вашем классе. Вариантов несколько: раз: присоединить к этому слоту сигнал и просигналить; два: QMetaObject::invokeMethod(); три: унаследовать таки временный класс от QThread, переопределив метод run(), в котором и вызвать метод в Вашем классе.

anonymous
()
Ответ на: комментарий от gDendy

Выдает ошибку на «Foo* foo = new Foo;». Как я понял это связанно с неопределенными виртуальными функциями. Какие функции я должен определить чтобы заработало?

Вам надо полностью описать класс Foo, я дал только заглушку

shty ★★★★★
()
Ответ на: комментарий от gDendy

Ошибку больше не дает, все нормально компилируется и работает, но поток не запускаеться. Что я не правильно сделал?? вот код main.cpp

#include "class.h"

int main(int argc, char **argv)
{
        QApplication app(argc,argv);
        QThread* thread = new QThread;
        Foo* foo = new Foo;

        foo->moveToThread(thread);
        thread->start();
        return app.exec();
}

мой косяк, вчера сонный был а ещё работать надо было :)

я вспомнил зачем start() :) конечно он там не просто так, и, конечно, он там использовался

#include "class.h"

int main(int argc, char **argv)
{
        QApplication app(argc,argv);
        QThread* thread = new QThread;
        Foo* foo = new Foo;

        foo->moveToThread(thread);

        // здесь цобаго!
        connect(thread, SIGNAL(started()), foo, SLOT(start()));

        thread->start();
        return app.exec();
}
shty ★★★★★
()
Ответ на: комментарий от seed_stil

приходилось когда-нибудь миксовать разные сигналы/слоты?

вопрос не понял :)

почему так? :)

для чего Q_SLOTS? он в том проекте с какими-то внутренностям boost'а мешался, ЕМНИП

shty ★★★★★
()
Ответ на: комментарий от shty

а может то не boost был, сейчас не помню :)

shty ★★★★★
()
Ответ на: комментарий от shty

>вопрос не понял :)

для чего Q_SLOTS? он в том проекте с какими-то внутренностям boost'а мешался, ЕМНИП

собственно об этом и спрашивал, в бусте свои сигналы

seed_stil ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.