1

对 Qt 太陌生了。阅读 wiki 和 C++ Gui 编程书,他们说子类 QThread。发现这不是现在推荐的方式。

所以我在这里有一些练习代码,我对这是否正确有一些疑问。所以我真的很感激有人看看。

因此,我创建了一个将 QThread 作为私有成员的类,用于 movetothread。创建它时,我确保不指定父级。因此我的第一个问题是,这样做可以吗?

第二个问题来自 m_thread->quit(); 我发现在我这样做之前,我的连接完成并没有被发出。那么这是正确的方法吗?我阅读了http://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/并看到在同一个线程中完成和 deleteLater 之间的连接但是不是 100% 确定这是否应该与退出一起使用。

最后,说到deleteLater,这是否意味着我不需要delete m_thread

感谢任何人的时间。

代码在这里。带有按钮的简单 QDialog。 工人.cpp

#include "worker.h"

worker::worker(QObject *parent) :
    QObject(parent)
{
    stopped = false;
}

void worker::setupAndRun()
{
    m_thread = new QThread();
    connect(m_thread,SIGNAL(started()),this,SLOT(doWork()));
    connect(m_thread,SIGNAL(finished()),this,SLOT(onComplete()));
    connect(m_thread,SIGNAL(finished()),m_thread,SLOT(deleteLater()));
    this->moveToThread(m_thread);
    m_thread->start();
}

void worker::doWork()
{

    for(int i = 0; i < 20000; i++)
    {
        if (this->stopped)
            break;
        qDebug() << i << " : " <<  Q_FUNC_INFO << m_thread->currentThreadId();
    }
    // --- I think the quit calls the finished signal?
    m_thread->quit();

}

void worker::onComplete()
{
    qDebug() <<  Q_FUNC_INFO << "Called " << m_thread->currentThreadId();
}

工人.h

#ifndef WORKER_H
#define WORKER_H

#include <QObject>
#include <QDebug>
#include <QThread>

class worker : public QObject
{
    Q_OBJECT
public:
    explicit worker(QObject *parent = 0);
    void setupAndRun();
signals:

public slots:
    void doWork();
    void onComplete();
private:
    // --- The thread that I use to movetothread with.
    // Is this ok?
    QThread *m_thread;
    bool stopped;
};

#endif // WORKER_H

对话框按钮

void Dialog::on_pushButton_clicked()
{
    m_worker = new worker();
    m_worker->setupAndRun();
}
4

1 回答 1

2

我一目了然并没有发现任何东西,但是有一些东西:

由于m_thread是成员变量,因此您应该以不同的方式处理它。您可以null在构造函数中将其初始化为,并m_thread = null在调用后设置m_thread->quit(),因为它会在不久之后被删除,并且您不想要一个悬空指针。

使用此代码,您也应该将完成的信号连接到 m_worker 的 deleteLater(),因为似乎没有其他代码可以删除它。您还应该在应用程序退出时处理线程,例如使用qAddPostRoutine,以便所有线程终止并删除所有相关对象。

于 2012-10-17T10:47:41.063 回答