1

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

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


我认为以以下方式重新实现 start 应该可以工作:(Zaehler 是 QThread)

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

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


问题: 我知道,应该避免弄乱启动和运行,但是有没有办法做到这一点?难道我做错了什么?

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

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

4

2 回答 2

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。

于 2013-04-12T12:57:14.967 回答
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/

于 2013-04-12T14:32:11.850 回答