QStandardItemModel的data线程安全(在插入数据时,临时禁止sizeHint去读model中的data)
在直接使用QStandardItemModel存取数据时,必须考虑线程安全问题
以下是使用场景:
QListView用于显示图片缩略图,而整个view有一万以上的缩略图,也就是说item项在一万以上
在大量的数据插入过程中,void QStandardItemModel::appendRow(QStandardItem *item) 这个函数是比较慢的,即使插入空的QStandarItem而不填充任何数据,一万项数据的插入操作也是秒级别的,所以需要用到线程来进行插入操作以下是问题:
在void QStandardItemModel::appendRow(QStandardItem *item) 运行于其他非UI主线程时,完成操作后UI会在更新数据后主动刷新,这时,QSize QStyledItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const函数会读取Qt::SizeHintRole的数据,我们就会遇到data的写跟读在不同线程同时被访问的问题以下是我的解决方法:
- 继承QAbstractItemModel实现数据读写,在读写过程中加入QMutex锁
- 在插入数据时,临时禁止sizeHint去读model中的data
明显,第一种方式更为合理,但是如果你项目比较紧急,用第二种方法吧,就酱。
////////////////////////////////上段代码方便记录//////////////////////////////////////////////
//1、大量数据准备好了,开始新线程插入数据到model
QtConcurrent::run(m_frames[currentTL], &TimelineViewFrame::insertItems, currentInfos);
//2、循环插入过程
void TimelineViewFrame::insertItems(const DBImgInfoList &infos)
{
using namespace utils::image;
for (auto info : infos) {
ThumbnailListView::ItemInfo vi;
vi.name = QByteArray::fromPercentEncoding(info.fileName.toUtf8());
vi.path = QByteArray::fromPercentEncoding(info.filePath.toUtf8());
vi.thumb = cutSquareImage(getThumbnail(vi.path, true));
m_view->insertItem(vi);
}
}
//3、每一个插入过程
void ThumbnailListView::insertItem(const ItemInfo &info)
{
// Diffrent thread connection cause duplicate insert
if (indexOf(info.path) != -1)
return;
m_model->appendRow(new QStandardItem());
QModelIndex index = m_model->index(m_model->rowCount() - 1, 0);
m_model->setData(index, QVariant(getVariantList(info)), Qt::DisplayRole);
m_model->setData(index, QVariant(iconSize()), Qt::SizeHintRole);
// updateViewPortSize();
}
https://blog.csdn.net/MatchYang/article/details/52988257
QStandardItemModel的data线程安全(在插入数据时,临时禁止sizeHint去读model中的data)的更多相关文章
- MySQL->>innodb_autoinc_lock_mode参数控制auto_increment 插入数据时相关锁的模式
转自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/15498/viewspace-2141640/ ---------------------------------- ...
- FreeSql (七)插入数据时忽略列
var connstr = "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;" + "Initia ...
- FreeSql (八)插入数据时指定列
插入数据时指定列,和忽略列对应,未被指定的列将被忽略. var connstr = "Data Source=127.0.0.1;Port=3306;User ID=root;Passwor ...
- Mybatis + Mysql 插入数据时中文乱码问题
近日跟朋友一起建立一个项目,用的是spring+mybatis+mysql. 今天碰到一个mybatis向mysql中插入数据时,中文显示为'???'的问题,拿出来说下. 对于数据库操作中出现的中文乱 ...
- 【JDBC】向数据表插入数据时,自动获取生成的主键
数据表设计时,一般都会有一个主键(Key)(自己指定),有时也可以使用联合主键: 有许多数据库提供了隐藏列为表中的每行记录分配一个唯一键值(如:rowid): 当我们没有指定哪一列作为主键key时,数 ...
- 触发器修改后保存之前的数据 表中插入数据时ID自动增长
create or replace trigger t before update on test5 for each rowbegin insert into test55 values (:old ...
- mysql插入数据时,中文乱码
MySQL 插入数据时,中文乱码问题的解决(转) 当向 MySQL 数据库插入一条带有中文的数据形如 insert into employee values(null,'张三','female','1 ...
- SqlBulkCopy批量插入数据时,不执行触发器和约束的解决方法
原文:SqlBulkCopy批量插入数据时,不执行触发器和约束的解决方法 在new SqlBulkCopy对象的时候,设置一下SqlBulkCopyOptions选项即可,按位或运算 SqlBulkC ...
- inserted触发器,一张表插入数据时,同时向另外一张表插入数据
有时候,一个服务器上有多个数据库,需要向其中一个数据库的表中插入数据时, 同时向另外一个数据的表里插入数据. 可以利用触发器和同义词(建立同义词的方法省略), 在一个数据库的表里插入数据时,同时向另外 ...
随机推荐
- android mvp高速开发框架介绍(dileber使用之图片下载工具)
这几天忙着工作- 今天抽时间又把框架的bug处理了一下--并且把volley的源代码改动了一下 android mvp框架:dileber(https://github.com/dileber/dil ...
- oracle存储过程的使用
一. 使用for循环游标:遍历全部职位为经理的雇员 1. 定义游标(游标就是一个小集合) 2. 定义游标变量 3. 使用for循环游标 declare -- 定义游标c_job cursor c_jo ...
- CSS中alt和title属性的正确使用
1.在<img>标签中的使用 alt:全称为alttext,实质是当图片无法正确显示时用于替换(在IE下同时起到了title的作用,即鼠标滑过时文字提示): title:鼠标经过时文字提示 ...
- 7.gcc的使用
什么是gcc gcc编译器(GNU C Compiler) 现在我们所说的 gcc 是 GUN Compiler Collection的缩写,可以支持多种语言编译,比如 C,C++,Java, pas ...
- HD-ACM算法专攻系列(16)——考试排名
问题描述: 源码: 主要要注意输出格式. #include"iostream" #include"iomanip" #include"algorith ...
- Array.prototype.slice.call(arguments) 通俗法理解
Array.prototype.slice.call(arguments,num) 能将具有length属性的对象转成数组. slice 从字面上的意思可以理解为截取数组的一部分. call 从字 ...
- DevExpress Report 打印提示one or more margins are set outside the printable area of the page 问题解决
DevExpress Report Print的时候,出现这样的问题:one or more margins are set outside the printable area of the pa ...
- ZBrush软件中的笔触类型
在ZBrush® 中我们通过各种笔触类型,确定在使用ZBrush®画笔进行绘制时画笔的变化方式及状态.使用多种画笔绘制根据选择不同的笔触组合绘制,能够得到繁多变化丰富的制作效果. 选择笔触的类型 点击 ...
- 堆————数据流的第k个大的元素
解题思路 一般地,堆和堆排序——解决 "贪心算法及其类似问题" 的利器. # 思路:我们可以用一个小根堆来做,并且限制堆的大小为k,初始化时把nums的每个数都push到堆中,如果 ...
- 路飞学城Python-Day32
36-进程池线程池 开多线程实现并发的效率是高的,当用户没有那么多的时候,服务器是可以承受压力的 但是一定要以某种方式来设置并发数,让服务器能够实现稳定的运行,控制服务器的线程数 设置池,往里面放池的 ...