QThread Class

news/2025/3/19 13:20:12/

QThread

  • QThread类
    • 枚举类型
    • 成员函数
    • 可重写函数
    • 公共槽
    • 信号
    • 静态成员函数
    • 保护函数
    • 静态保护函数
    • QThread简单案例1
    • QThread简单案例2


QThread类

标准头文件:#include <QThread>
qmake:	QT += core
继承():	QObject

枚举类型

线程的优先级

enum Priority { IdlePriority, LowestPriority, LowPriority, NormalPriority, HighPriority,, InheritPriority }

{ 空闲优先级,最低优先级,低优先级,正常优先级,高优先级,…,继承优先级 }

此枚举类型指示操作系统应该如何调度新创建的线程。

常数价值描述
QThread::IdlePriority0仅在没有其他线程运行时调度。
QThread::LowestPriority1调度频率低于低优先级。
QThread::LowPriority2计划频率低于正常优先级。
QThread::NormalPriority3操作系统的默认优先级。
QThread::HighPriority4比正常优先级计划得更频繁。
QThread::HighestPriority5比高优先级计划得更频繁。
QThread::TimeCriticalPriority6尽可能经常安排。
QThread::InheritPriority7使用与创建线程相同的优先级。这是默认值。

成员函数

类型方法说明
构造函数QThread(QObject *parent = nullptr)参数父类QObject指针
virtual~QThread()虚析构函数,当基类指针指向子类时,使用delete时,会先调用子类析构函数,在调用父类构造函数,释放资源。
QAbstractEventDispatcher *eventDispatcher() const
voidexit(int returnCode = 0)
boolisFinished() const
boolisInterruptionRequested() const
boolisRunning() const
intloopLevel() const
QThread::Prioritypriority() const
voidrequestInterruption()
voidsetEventDispatcher(QAbstractEventDispatcher *eventDispatcher)
voidsetPriority(QThread::Priority priority)
voidsetStackSize(uint stackSize)
uintstackSize() const
boolwait(QDeadlineTimer deadline = QDeadlineTimer(QDeadlineTimer::Forever))阻塞线程,直到满足以下任一条件,这提供了与POSIX pthread_join()函数相似的功能。
boolwait(unsigned long time)

可重写函数

virtual bool	event(QEvent *event) override

公共槽

何为公共槽函数,就是可以被子类直接调用

void	quit()
void	start(QThread::Priority priority = InheritPriority)
void	terminate()

信号

void	finished()
void	started()

静态成员函数

QThread *	create(Function &&f, Args &&... args)
QThread *	create(Function &&f)
QThread *	currentThread()
Qt::HANDLE	currentThreadId()
int		idealThreadCount()
void	msleep(unsigned long msecs)
void	sleep(unsigned long secs)
void	usleep(unsigned long usecs) //强制当前线程休眠微秒。
//[将当前线程的执行让给另一个可运行线程(如果有)。请注意,操作系统决定切换到哪个线程。]
void	yieldCurrentThread()

保护函数

int	exec()
virtual void	run()

静态保护函数

基于enabled参数启用或禁用当前线程的终止。线程必须是由QThread启动的。

void	setTerminationEnabled(bool enabled = true)

QThread简单案例1

官方的例子,值得信赖
例如:Worker 是我们创建的一个子线程。
继承QObject的优点:内存回收安全,支持信号与槽。

例如:Controller 是主线程。

共同点:他们都继承自QObject

代码里面的connect的这种写法我比较推荐,参数怎么变都不影响,减少修改次数

这种线程的特点:任务线程里面的每个槽函数都是一个事件循环,即你可以处理耗时操作,读写文件,数据计算,大量循环等等(目前我我是使用这种方法,还不错)。

class Worker : public QObject
{Q_OBJECTpublic slots:void doWork(const QString &parameter) {QString result;/* ... 处理大数据 ... */emit resultReady(result); //处理完数据,发到主线程显示}signals:void resultReady(const QString &result);
};class Controller : public QObject
{Q_OBJECTQThread workerThread;//线程栈 自动销毁,推荐使用
public:Controller() {Worker *worker = new Worker; //创建任务子线程worker->moveToThread(&workerThread);	//添加到线程,实际应该可以添加多个任务子线程。connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);//线程完成这个任务,就将这个任务线程对象删除connect(this, &Controller::operate, worker, &Worker::doWork);//发射信号,通知任务线程做事。connect(worker, &Worker::resultReady, this, &Controller::handleResults);//接收任务子线程处理好的数据workerThread.start(); //正式开启线程,}~Controller() {workerThread.quit();	//先退出没处理的任务workerThread.wait();	//已经在处理的任务,等待处理完,在退出}
public slots:void handleResults(const QString &);
signals:void operate(const QString &);
};

任务插槽中的代码将在一个单独的线程中执行。但是,您可以自由地将任务线程的插槽连接到来自任何对象、任何线程的任何信号。由于一种称为排队连接的机制跨不同线程连接信号和插槽是安全的

QThread简单案例2

让代码在单独的线程中运行的另一种方法是子类化QThread并重新实现run()。这种使用的场景一般是不需要和主线程交互,比如只完成文件写操作等等。
例如:

//任务线程
class WorkerThread : public QThread
{Q_OBJECTvoid run() override {QString result;/* ... here is the expensive or blocking operation ... */emit resultReady(result);}
signals:void resultReady(const QString &s);
};
//主线程 分配任务
void MyObject::startWorkInAThread()
{WorkerThread *workerThread = new WorkerThread(this);//传入this,就是QObject的指针,资源的释放,即是线程的构造函数传参。connect(workerThread, &WorkerThread::resultReady, this, &MyObject::handleResults);connect(workerThread, &WorkerThread::finished, workerThread, &QObject::deleteLater);workerThread->start();//开启run()方法
}

在该示例中,线程将在run函数返回后退出。除非调用exec(),否则线程中不会运行任何事件循环(即做完这件事,就不再执行事件循环了)。


重要的是要记住,QThread实例存在于实例化它的旧线程中,而不是存在于调用run()的新线程中。这意味着所有QThread的队列槽和调用的方法都将在旧线程中执行。因此,希望在新线程中调用槽的开发人员必须使用工作对象方法;新插槽不应该直接在子类化的QThread中实现。


与排队槽或调用的方法不同,直接在QThread对象上调用的方法将在调用该方法的线程中执行。当子类化QThread时,请记住构造函数在旧线程中执行(主线程id一致),而run()在新线程中执行(线程id新的)。如果一个成员变量是从两个函数中访问的,那么这个变量是从两个不同的线程中访问的。检查这样做是否安全。


注意:在跨不同线程与对象交互时必须小心。一般来说,函数只能从创建QThread对象本身的线程中调用(例如setPriority()),除非文档中另有说明。


http://www.ppmy.cn/news/96907.html

相关文章

scipy库统计模块stats

# 统计相关模块stats sp.stats.norm.rvs()#标准正态分布 sp.stats.norm.fit()#估算正态分布的参数 sp.stats.norm.pdf()#计算对应位置的概率密度 sp.state.norm.ppf()#找到标准正态分布中概率恰好为一半的点 sp.stats.expon()#指数分布 sp.stats.norm.cdf()#累积分布函数 sp.st…

linux中和,|和||及分号(;)的用法

在linux中&#xff0c;我们经常会用到&和&&&#xff0c;|和||及分号(;)&#xff0c;但是好多人对其会混淆&#xff0c;不明白其中的意思&#xff0c;今天为大家讲解一下&和&&&#xff0c;|和||及分号(;)各自的说明和用法。 1.& & 表示程序…

【Cookie和Session】

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔&#x1f93a;&#x1f93a;&#x1f93a; 目录 一、Cookie和Session&#xff08;面试常考&…

ChatGPT与讯飞星火实测对比

文章目录 一、推理测试测试提示词1&#xff1a;假设树上有10只鸟&#xff0c;开枪打死1只&#xff0c;那么树上还有几只鸟?- 测试提示词2&#xff1a;一艘船10天可以渡过太平洋&#xff0c;请计算10艘船多少天可以渡过太平洋。测试提示词3&#xff1a;我爸妈结婚的时候为什么不…

Qt - UI进阶

Qt - UI 进阶 布局控件及其坐标pos/position/scenePosition/globalPosition 场景和视图&#xff1f;&#xff1f;&#xff1f; 布局 https://blog.csdn.net/kongcheng253/article/details/128769765 控件及其坐标 pos/position/scenePosition/globalPosition pos()函数返回的…

动态组件、插槽、自定义指令、Eslint和prettierrc配置、axios全局挂载

动态组件、插槽、自定义指令、Eslint和prettierrc配置、axios全局挂载 动态组件插槽体验插槽的基础用法作用域插槽 自定义指令Eslint和prettierrc配置prettierrc axios全局挂载 动态组件 动态组件指的是动态切换组件的显示与隐藏。 如何实现动态组件渲染 vue 提供了一个内置的…

《Spring Guides系列学习》guide51 - guide55

要想全面快速学习Spring的内容&#xff0c;最好的方法肯定是先去Spring官网去查阅文档&#xff0c;在Spring官网中找到了适合新手了解的官网Guides&#xff0c;一共68篇&#xff0c;打算全部过一遍&#xff0c;能尽量全面的了解Spring框架的每个特性和功能。 接着上篇看过的gui…

英睿达内存条正品鉴别教程(镁光颗粒)

我们打算买一款二手镁光颗粒的英睿达内存条,需要从正面内存标签上的条形码、字串,从背面颗粒上的两行字符一一分析、检查、鉴别,最终确认是否正品,以及内存条等级如何。通过本片文章,您能学会如何进行镁光颗粒的英睿达内存条正品鉴别。 一、标签检查 首先,用百度条形码…