我从多线程开始,并且在将对象移动到QThread时遇到了一些麻烦。我的Controller类实例化Worker,为Worker创建必要的线程并将Worker移动到新线程。工作线程启动时,工作人员的计算开始。 Worker类包含一个Dummy对象,该对象在工作计算期间使用(函数Dummy::doDummyStuff()
)。一切似乎工作正常,除了doDummyStuff()
似乎在主(控制器)线程而不是工作线程中执行。这是因为在主线程中首先创建了Worker对象(以及Dummy对象)吗?有没有办法在工作线程中移动Worker对象的所有类成员?
以下是代码段:
或者Controller.h
class Controller: public QObject
{
Q_OBJECT
public:
Controller(std::vector<double> _data, QString _fn);
void startControl();
private:
QThread workerThread_;
Worker worker_;
PostProcessing postProc_;
};
Controller.cpp
Controller::Controller(std::vector<double> _data, QString _fn): QObject(), workerThread_(), worker_(_data), postProc_()
{
QObject::connect(&workerThread_, SIGNAL(started()), &worker_, SLOT(doWork()));
QObject::connect(&worker_, SIGNAL(signalResultReady(double)), &postProc_, SLOT(update(double)));
}
void Controller::startControl()
{
worker_.moveToThread(&workerThread_);
workerThread_.start();
}
Worker.h
class Worker: public QObject
{
Q_OBJECT
public:
Worker(std::vector<double> _coord);
signals:
void signalResultReady(double);
public slots:
void doWork();
private:
double res_;
std::vector<double> coord_;
Dummy dummyCreatedInWorker_;
};
Worker.cpp
Worker::Worker(std::vector<double> _coord): QObject(), res_(0), coord_(_coord), dummyCreatedInWorker_()
{
}
void Worker::doWork()
{
qDebug() << "Worker thread ID" << this->thread();
for(unsigned int ii = 0; ii < coord_.size(); ii++)
{
res_ += coord_[ii];
dummyCreatedInWorker_.doDummyStuff();
emit signalResultReady(res_);
/* ....*/
}
}
假人:: doDummyStuff
void Dummy::doDummyStuff()
{
qDebug() << "Doing dummy stuff from thread" << this->thread();
for(int ii = 0; ii < 10; ii++)
{
res_ += ii;
}
}
答案 0 :(得分:3)
您的虚拟类也来自QObject?
如果您将虚拟对象设置为工作人员的子节点,则在调用moveToThread时它将自动移动。
即。如果它没有隐藏默认的qobject构造函数,则将worker传递给dummy的构造函数:
Worker::Worker(std::vector<double> _coord):
QObject(), res_(0), coord_(_coord), dummyCreatedInWorker_(this)
或者,您可以在worker 和虚拟对象上调用moveToThread。
但是,即使没有更改任何内容,也会在工作线程中调用Dummy::doDummyStuff()
。
调用任何东西都不会改变线程,只会发出(排队)信号。
但是你不能使用this->thread()
来检查调用该方法的线程。它返回对象&#34;所在的线程&#34;,即,如果由信号调用,则调用该对象的(排队)槽的线程。
而是使用QThread::currentThread()
来查看调用方法的线程。
你可以在任何线程中调用任何对象的任何方法,它完全独立于对象和线程之间的关联