我有一个类,它是某些设备的抽象。
class Device
{
public:
...
void Start();
void Stop();
void MsgLoop();
signals:
void sMsgArrived();
}
从GUI线程调用Start()和Stop()。 Start()开始新线程,该线程运行MsgLoop()。看起来像这样:
void MsgLoop()
{
forever {
if(SUCCESS == ReadMsg()) //synchronous, non-blocking
{
ProcessMsg(); //quite fast
emit sMsgArrived(); //this signal is connected with a slot in GUI thread
}
}
}
调用Stop()时,程序应从MsgLoop()返回并停止线程。如何在不子类化的情况下用QThread实现呢?
最佳答案
通常,您必须确定谁将负责管理线程。是设备还是主窗口?或者可能是一些设备管理器。在您的情况下,设备可能应该管理自己的线程,因此,如果您不想对其进行子类化,请使用composition:
class Device : QObject
{
Q_OBJECT
public:
Device(QObject * parent = NULL);
void Start();
void Stop();
private slots:
void MsgLoop();
signals:
void sMsgArrived();
private:
QThread thread;
bool stopThread;
};
Device::Device(QObject * parent) : QObject(parent)
{
moveToThread(&thread);
connect(&thread, SIGNAL(started()), this, SLOT(MsgLoop()));
}
void Device::Start()
{
stopThread = false;
thread.start();
}
void Device::Stop()
{
stopThread = true;
thread.wait(); // if you want synchronous stop
}
void Device::MsgLoop()
{
// your loop
while(!stopThread)
if(SUCCESS == ReadMsg())
{
ProcessMsg();
emit sMsgArrived();
}
QThread::currentThread->quit();
}
注意:只有在
ReadMsg
确实是非阻塞的情况下,线程停止才会起作用。如果您以后决定切换到阻止读取(这在大多数情况下可能是适当的),那么您将不得不找出另一种方法来停止线程。