我有一个暴露于QML的课程:
qmlRegisterType(“SerialThread”,1,0,“SerialThread”);
该类继承QThread,QThread.start()从QML调用。
当用户关闭应用程序时,如何在程序终止之前正确退出线程?
答案 0 :(得分:3)
在析构函数中,您应该调用quit()
,然后调用wait()
。因为,希望你已经让QML拥有了线程对象,它会破坏它 - 随意验证析构函数实际上已被执行。
如果你没有在线程中旋转事件循环,那么你必须重新实现quit()
来设置你自己的停止标志。由于您隐藏了基础非虚拟quit()
,因此您的“线程”不再是QThread
,并且您必须私下继承QThread
- 这是一个否则会出现语义错误(并导致错误)。
如何发生此类错误?既然你可以在一个QThread
的某个地方传递你的“不完全”的线程,那么它的那些用户可以自由地认为它是一个真正的线程,而不是“不是一个”,并调用QThread::quit()
方法,这是一个没有事件循环的无操作。因此错误。
要维护LSP,如果需要覆盖非虚拟公共方法,则必须私有地从父类继承,因为它在父级可用的地方不可用。
class MyThread : private QThread {
Q_OBJECT
Q_DISABLE_COPY(MyThread)
volatile bool m_stop;
void run() { ... }
public:
MyThread(QObject * parent = nullptr) : QThread(parent) { ... }
void quit() { m_stop = true; }
// It's important to fully qualify the Priority type, otherwise moc will generate
// wrong code.
Q_SLOT void start(QThread::Priority priority = InheritPriority) {
if (isRunning()) return;
m_stop = false;
QThread::start();
}
using QThread::isRunning;
using QThread::isFinished;
bool isInterruptionRequested() const { return m_stop; }
~MyThread() {
quit();
wait();
}
// Publicly we're only a QObject, not a thread
operator QObject&() { return *this; }
operator const QObject&() const { return *this; }
void run() {
while (!m_stop) { ... }
}
};
答案 1 :(得分:0)
你可以在main中返回退出值之前调用thread.stop()并检查thread.is Running()。