重新实现QThread的start()

时间:2013-04-12 12:39:46

标签: c++ qt

我在Qt练习线程。我重新实现run()(尽管不推荐),一切正常。

现在我想通过让它传递变量run()来为run(int i)添加更多功能。 此外,我希望调用run的start()将变量传递给run(int i)start(int j)


我认为重新实现以下列方式启动应该有效:(Zaehler是QThread)

void Zaehler::start(int ZaehlerIndex) { run(ZaehlerIndex), terminate(); }

嗯,它没有。我的GUI在启动线程时冻结。


问题: 我知道,应该避免搞乱开始和运行,但有没有办法做到这一点?我做错了吗?

注: 我查了qthread.cpp,看看start()是如何实现的,但我找到的只是

\sa run(), terminate()被注释掉了!所以它实际上甚至不应该工作!?

2 个答案:

答案 0 :(得分:0)

如果你想在线程内部启动一个函数并传递一些参数这个函数,我建议使用这个方法:

class MyWorker: public QThread
{
  Q_OBJECT
public:
    MyWorker()
    {
        start();
    }

    virtual ~MyWorker()
    {
        quit();
        wait();
    }

    // your function to call inside thread
    Q_INVOKABLE void doSomeWork(int data)
    {
        // check if we called from another thread
        if (QThread::currentThread() != this)
        {
            // re-call self from very own thread
            QMetaObject::invokeMethod(this, "doSomeWork",
                                      Qt::BlockingQueuedConnection,
            // or Qt::QueuedConnection if you want to start it asynchronously
            //  and don't wait when work finished
                                      Q_ARG(int, data));
            return;
        }

        // this will be started within your thread
        // some useful work here
    }
};

如果您的线程没有run()方法,将使用QEventLoop,您可以在线程上下文中调用您的方法。

您也可以将方法声明为插槽并使用排队连接进行调用,而不是Q_INVOKABLE。

答案 1 :(得分:0)

这样的事情怎么样?

class Worker
{
    //note, only pass parameters by copy here.
    public: 
        Worker(int param) : myParam(param) {}

    public slots:
        void process()
        {
            //do something with myParam here, it will run in the thread.
        }

    signals:
        void finished();
        void error(QString err);

    private:
        int myParam;
};

然后可以使用“moveToThread”连接到线程对象,如下所示:

QThread* thread = new QThread;
Worker* worker = new Worker(5);
worker->moveToThread(thread);
connect(worker, SIGNAL(error(QString)), this, SLOT(errorString(QString)));
connect(thread, SIGNAL(started()), worker, SLOT(process()));
connect(worker, SIGNAL(finished()), thread, SLOT(quit()));
connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->start();

有关Qt中线程使用情况的更多信息和简短教程,请参阅此处: http://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/