我正在尝试将Qthread与对象配合使用。为此,编写以下代码:
QThread *thread1 = new QThread();
serialclass *obje = new serialclass();
void MainWindow::on_pushButton_baglan_clicked()
{
obje->moveToThread(thread1);
connect(thread1,SIGNAL(started()),obje,SLOT(baglan()), Qt::UniqueConnection);
connect(obje,SIGNAL(finished()),thread1,SLOT(quit())); //end of the baglan function finished() signal is emitted.
thread1->start();
}
我的代码有效。但是我使用了quit(),而不是deletelater()。该按钮可以被按下很多次。第一个问题是,此方法正确吗?我的第二个问题是,如果我长时间按下按钮会发生什么情况。有很多线吗?每次创建一个线程吗?
这可以。您应该了解自己的工作及其原因:代码及其目的应该来自您以及您的理解。
当您多次按下按钮时,该应用程序可能处于以下两种状态之一:
线程已经完成:obje->thread() == nullptr
并且您正在重新启动线程-它将正常工作。
该线程仍在运行:obje->thread() == thread1
两者moveToThread
并thread1->start()
没有执行任何操作。
las,停止线程没有意义。它具有一个事件循环,该循环直到新事件到达之前才被阻止,这好像没有空闲状态QThread
正在耗尽任何CPU一样。启动线程很昂贵:它会创建一个新的本机线程。完成的线程不复存在:是的,您仍然有一个QThread
,但这就像拥有一个关闭文件的句柄一样。QThread
毕竟是线程句柄。
您应该按值而不是按指针保留成员-这样可以避免通过点对额外间接的愚蠢过早的悲观化。您可以提前设置所有连接。您不需要on_pushButton_baglan_clicked()
插槽:您可以将按钮直接与SerialClass
实例连接。您还应该使用QThread
可安全销毁的-derived类。
您的代码如下所示。编译器将为您生成一个适当的资源分配析构函数。这是编译器的工作,它永远不会让您失败—而人类开发人员很容易失败。因此,您应该充分利用RAII的优势,因为它将RAIA手动操作转移到了可以完美完成并且几乎没有效果的机器上:)
// MyWindow.h
#include <QMainWindow>
#include <QThread>
#include "SerialClass.h"
#include "ui_MyWindow.h"
class MyWindow : public QMainWindow {
Q_OBJECT
class SafeThread : public QThread {
using QThread::run; // final
public:
~SafeThread() { quit(); wait(); }
} m_serialThread;
SerialClass m_serial;
Ui::MyWindow ui;
public:
MyWindow(QWidget * parent = nullptr);
};
// MyWindow.cpp
#include "MyWindow.h"
MyWindow::MyWindow(QWidget * parent) :
QMainWindow{this}
{
ui.setupUi(this);
connect(ui.pushButton_baglan, &QPushButton::clicked,
&m_serial, &SerialClass::baglan);
m_serial.moveToThread(&m_serialThread);
m_serialThread.start();
}
如果您不希望所有实现细节都包含在MyWindow
的标头中,则应使用PIMPL。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句