我在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()
被注释掉了!所以它实际上甚至不应该工作!?
答案 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/