Слот Qt moveToThread не вызывается

У меня есть класс Manager

class Manager : public QThread 
{
    Q_OBJECT
    public:
    Manager();
    void run()
    {
        taskB = new TaskB();
        taskA = new TaskA();
        connect(taskA, SIGNAL(signalOk()), taskB, SLOT(onSignalOk()));
        connect(taskA, SIGNAL(moveOk()), taskB, SLOT(onMoveOk()));
        connect(taskB, SIGNAL(signal()), taskA, SLOT(onSignal()));
        connect(taskB, SIGNAL(moveToThreadSignal(QThread*)), taskA, SLOT(onMoveToThread(QThread*)));
        connect(this, SIGNAL(runSignal()), taskB, SLOT(onRun()));
        emit runSignal();
    }
    TaskA* taskA;
    TaskB * taskB;
    signals:
    void runSignal();
    };

У меня также есть класс TaskA:

class TaskA : public QObject
{
    Q_OBJECT
    public:
    TaskA();
    void run()
    {
        std::cout << "[INFO] : Task run: " << QThread::currentThreadId() << std::endl;
        emit signalOk();
    }
    public slots:
    void onSignal()
    {
        run();
    }
    void onMoveToThread(QThread * t)
    {
        std::cout << "[INFO] : Task A after move to thread: " << QThread::currentThreadId() << std::endl;
        this->moveToThread(t);
        std::cout << "[INFO] : Task A after move to thread: " << QThread::currentThreadId() << std::endl;
        emit moveOk();
    }
    signals:
    void signalOk();
    void moveOk();
};

А еще у меня есть такой класс TaskB

class TaskB : public QObject
{
    Q_OBJECT
    public:
    TaskB();
    void run()
    {
        std::cout << "[INFO] : TaskB run: " << QThread::currentThreadId() << std::endl;
        emit signal();
    }
    signals:
    void signal();
    void moveToThreadSignal(QThread* t);
    public slots:
    void onSignalOk()
    {
        std::cout << "[INFO] : TaskB onSignalOk : " << QThread::currentThreadId() << std::endl;
    }
    void onMoveOk()
    {
        std::cout << "[INFO] : TaskB onMoveOk: " << QThread::currentThreadId() << std::endl;
        run();
    }
    void onRun()
    {
        std::cout << "[INFO] : TaskB emit MoveToThreadSignal: " << QThread::currentThreadId() << std::endl;
        thread = new QThread();
        thread->start();
        emit moveToThreadSignal(thread);
    }
    private:
    QThread * thread;
};

Когда я запускаю менеджер с помощью:

Менеджер *_manager = новый менеджер();

_менеджер->старт();

слот onSignalOk() из TaskB не называется.

Я думаю, что причиной проблемы является параметр по умолчанию Qt::AutoConnection, когда я подключаю свой сигнал, но я не понимаю.


person artoon    schedule 14.08.2014    source источник
comment
Здесь есть и другие проблемы, и вам нужно подумать о сходстве потоков. Я рекомендую вам начать с прочтения этой статьи: mayaposch.wordpress.com/2011/11/01/   -  person TheDarkKnight    schedule 14.08.2014
comment
это название вводит в заблуждение. Внутри Qt есть функция movetoThread и функция, которую вы назвали movetoThreadSignal. Большая разница.   -  person UmNyobe    schedule 14.08.2014
comment
давайте сделаем шаг назад. Что вы пытаетесь сделать в конечном итоге? В приведенном выше коде много недостатков. особенно thread = new QThread();thread->start();. Что вы ожидаете от этого кода?   -  person UmNyobe    schedule 14.08.2014
comment
Этот код является только скамейкой. Мой проект - диспетчер задач. TaskB — это задача для параллельного запуска другой задачи (например, TaskA).   -  person artoon    schedule 14.08.2014
comment
Спасибо @Merlin069 за его комментарий. Этой статьей я поправил свой менеджер и теперь он работает. Менеджер наследует QObject, а не QThread, тогда я использую moveToThread.   -  person artoon    schedule 14.08.2014
comment
Пожалуйста. Я записал ответ, так что вы тоже можете пометить вопрос как отвеченный ;O)   -  person TheDarkKnight    schedule 14.08.2014


Ответы (1)


Я предлагаю начать с отказа от наследования QThread; его имя вводит в заблуждение, так как это скорее диспетчер потоков. На мой взгляд, единственная причина для наследования от QThread — это если вы хотите изменить то, как Qt управляет потоками.

Вместо этого просто наследуйте от QObject и переместите объект в новый поток. Преимущество этого заключается в возможности перемещать несколько объектов в один новый поток вместо того, чтобы создавать отдельный поток для каждого объекта, если вы наследуете QThread.

person TheDarkKnight    schedule 14.08.2014