QThread上的函数永远不会被调用

时间:2015-11-17 22:29:38

标签: qt qt5 qthread qt5.5

我试图在一个单独的线程上进行一些繁重的计算,所以我不会冻结UI。为此,我使用的是Qt 5.5。

我试图从官方网站实现工作线程example,但不幸的是没有取得多大成功。您可以在下面看到我的代码:

main.cpp中:

int main(int argc, char* argv[]) {
    QApplication app(argc, argv);

    DepthMap* depthmap = new DepthMap();
    DepthMapGrabber* grabber = new DepthMapGrabber(depthmap);

    PointCloudWindow myPointCloudWindow;
    myPointCloudWindow.setDepthMap(grabber);
    myPointCloudWindow.show();

    ProcessorController* controller = new ProcessorController(depthmap);
    controller->startThread();

    return app.exec();
} 

ProcessController.h:

class ProcessorController : public QObject
{
Q_OBJECT
// functions
private:
    QThread workerThread;

public:
    ProcessorController(const DepthMap* depthmap);
    ~ProcessorController();

    void startThread();

public slots:
    void handleResults(const QString &);

signals:
    void operate(const QString &);

// variables
private:
    Processor* m_processor;
};

ProcessController.cpp:

ProcessorController::ProcessorController(const DepthMap* depthmap) {
    m_processor = new Processor(depthmap);
}

ProcessorController::~ProcessorController() {
    if (m_processor != nullptr) {
        delete m_processor;
        m_processor = nullptr;
    }

    workerThread.quit();
    workerThread.wait();
}

void ProcessorController::startThread() {
    m_processor->moveToThread(&workerThread);
    connect(&workerThread, &QThread::finished, m_processor, &QObject::deleteLater);
    connect(this, &ProcessorController::operate, m_processor, &Processor::doWork);
    connect(m_processor, &Processor::resultReady, this, &ProcessorController::handleResults);
    workerThread.start();

    // LOG
    std::cout << "Worker thread has been started!" << std::endl;
}

void ProcessorController::handleResults(const QString &) {
    // LOG
    std::cout << "Worker thread finished!" << std::endl;
}

Processor.h:

class Processor : public QObject
{
Q_OBJECT

// functions
public:
    Processor(const DepthMap* depthmap);

public slots:
    void doWork(const QString &parameter);

signals:
    void resultReady(const QString &result);

// variables
private:
    QMutex m_mutex;
    const DepthMap* m_depthmap;
};

Processor.cpp:

Processor::Processor(const DepthMap* depthmap) : m_depthmap(depthmap) {}

void Processor::doWork(const QString &parameter) {
    // LOG
    std::cout << "Worker thread is working..." << std::endl;

    QString result;

    // copy cloud and work on the copy
    PointCloudPtr myCloud;
    m_mutex.lock();
    pcl::copyPointCloud(*m_depthmap->cloud, *myCloud);
    m_mutex.unlock();

    /* ... here is the expensive or blocking operation ... */

    emit resultReady(result);
}

问题是,来自处理器的 doWork 永远不会被调用。我究竟做错了什么?提前感谢您的任何解释和帮助!

编辑:

如果我把

QString result;
emit operate(result);

workerThread.start();

startThread()中,线程被执行!

任何人都可以解释一下这背后的机制是什么?

1 个答案:

答案 0 :(得分:1)

很长一段时间,Qt在我们能够操作的线程上提供虚拟任务对象。这是通过QObject :: moveToThread实现的,并且QObject派生的对象必须具有从中启动作业的槽。在这种情况下,插槽是doWork,并且连接到信号操作。

connect(this, &ProcessorController::operate, m_processor, &Processor::doWork);

这就是原因:

emit operate(desiredStr);

应该解决问题。

顺便说一句。如果不需要用户定义信号的特定推送,我们总是可以使用QThread :: started信号。在这种情况下,doWork插槽不会接收参数。

connect(&workerThread, &QThread::started, m_processor, &Processor::doWorkNoParams);