一、多线程
1、 复现未响应
使用线程类QThread的睡眠函数可以非常简单且精准的模拟阻塞:
// 强制当前线程睡眠一段时间
// 参数为睡眠的秒数
void QThread::sleep(unsigned long secs)
2 、创建并启动线程
创建并启动一个子线程的操作步骤如下:
1. 选中项目名称,鼠标右键,点击“添加新文件”。
2. 按照下图所示进行操作。
3. 设置继承结构。
4. 项目管理界面,直接点击“完成”。可以看到对应的文件。
5. 自定义线程类的头文件和源文件还需要修改。
6. 进入自定义线程类的头文件,覆盖基类QThread的run函数。
// 此函数相当于子线程的主函数,调用start函数后,新创建的线程自动调用此函数。
void QThread::run() [protected virtual]
7. 在run函数的函数体中,编写子线程要执行的逻辑。需要注意的是,子线程不能执行任何UI操作,如果子线程的run函数需要用到UI的相关参数,需要主线程(父对象)给子线程(子对象)传参(成员函数)。
8. 在主线程中创建子线程对象,并调用start函数启动子线程。
// 启动子线程
// 参数:子线程的优先级
void QThread::start(Priority priority = InheritPriority) [slot]
3 、异步刷新
在实际的开发中,两个线程通常要进行数据交互,相比于5.2节,更常见的场景是异步刷新。异步刷新指的是,子线程执行耗时操作,主线程根据子线程耗时操作的参数在UI进行刷新。
异步刷新问题可以归纳为子线程给主线程传参问题,即子对象给父对象传参——信号槽。
4 、停止线程
停止线程的一些方法:
- 调用terminate函数
// 强行停止线程,比较危险,不推荐使用
void QThread::terminate() [slot]
- 使用标志位
可以在耗时的循环体中添加标志位,通过停止循环间接让run函数执行完,达到停止线程的效果。
二、 数据持久化
数据持久化:将内存中的数据模型转换为存储模型,以及将存储模型转换为内存中的数据模型的统称。
之前数据库就是一种数据持久化的方式,但是虽然嵌入式使用的SQLite数据库已经是轻量级数据库,但是相对于其他技术,还是一种比较“重”的数据持久化方式。
Qt中提供比数据库更轻量级的数据持久化方式——QSettings
相关函数如下:
// 构造函数
// 参数1:存储文件的名称,默认为构建目录
// 参数2:存储格式
// 参数3:父对象
QSettings::QSettings(const QString & fileName, Format format, QObject * parent = 0)
// 设置INI文件的编码,建议使用UTF-8
// 参数:编码字符串
void QSettings::setIniCodec(const char * codecName)
// 开始存储,相同类型数据建议使用此函数,以数组方式存储
// 参数:数组的名称
void QSettings::beginWriteArray(const QString & prefix)
// 开始存储,不同类型的数据建议使用此函数(相同类型也可以,但是性能不如上面的好),以组方式存储
// 参数:组的名称
void QSettings::beginGroup(const QString & prefix)
// 在组中添加键值对
// 参数1:键
// 参数2:值
void QSettings::setValue(const QString & key, const QVariant & value)
// 结束数组/组的存储
void QSettings::endArray()
void QSettings::endGroup()
标签:QSettings,const,函数,void,线程,参数,多线程 From: https://blog.csdn.net/weixin_63207763/article/details/143122596// 根据键获得值
// 参数1:键
// 参数2:如果取出失败的默认值
// 返回值:值
QVariant QSettings::value(const QString & key, const QVariant & defaultValue = QVariant()) const