版权声明:本文为博主原创文章,欢迎转载,转载请注明出处 https://blog.csdn.net/MatchYang/article/details/52988257

在直接使用QStandardItemModel存取数据时,必须考虑线程安全问题

  1. 以下是使用场景: 
      QListView用于显示图片缩略图,而整个view有一万以上的缩略图,也就是说item项在一万以上 
    在大量的数据插入过程中,void QStandardItemModel::appendRow(QStandardItem *item) 这个函数是比较慢的,即使插入空的QStandarItem而不填充任何数据,一万项数据的插入操作也是秒级别的,所以需要用到线程来进行插入操作

  2. 以下是问题: 
      在void QStandardItemModel::appendRow(QStandardItem *item) 运行于其他非UI主线程时,完成操作后UI会在更新数据后主动刷新,这时,QSize QStyledItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const函数会读取Qt::SizeHintRole的数据,我们就会遇到data的写跟读在不同线程同时被访问的问题

  3. 以下是我的解决方法:

    • 继承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)的更多相关文章

  1. MySQL->>innodb_autoinc_lock_mode参数控制auto_increment 插入数据时相关锁的模式

    转自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/15498/viewspace-2141640/ ---------------------------------- ...

  2. FreeSql (七)插入数据时忽略列

    var connstr = "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;" + "Initia ...

  3. FreeSql (八)插入数据时指定列

    插入数据时指定列,和忽略列对应,未被指定的列将被忽略. var connstr = "Data Source=127.0.0.1;Port=3306;User ID=root;Passwor ...

  4. Mybatis + Mysql 插入数据时中文乱码问题

    近日跟朋友一起建立一个项目,用的是spring+mybatis+mysql. 今天碰到一个mybatis向mysql中插入数据时,中文显示为'???'的问题,拿出来说下. 对于数据库操作中出现的中文乱 ...

  5. 【JDBC】向数据表插入数据时,自动获取生成的主键

    数据表设计时,一般都会有一个主键(Key)(自己指定),有时也可以使用联合主键: 有许多数据库提供了隐藏列为表中的每行记录分配一个唯一键值(如:rowid): 当我们没有指定哪一列作为主键key时,数 ...

  6. 触发器修改后保存之前的数据 表中插入数据时ID自动增长

    create or replace trigger t before update on test5 for each rowbegin insert into test55 values (:old ...

  7. mysql插入数据时,中文乱码

    MySQL 插入数据时,中文乱码问题的解决(转) 当向 MySQL 数据库插入一条带有中文的数据形如 insert into employee values(null,'张三','female','1 ...

  8. SqlBulkCopy批量插入数据时,不执行触发器和约束的解决方法

    原文:SqlBulkCopy批量插入数据时,不执行触发器和约束的解决方法 在new SqlBulkCopy对象的时候,设置一下SqlBulkCopyOptions选项即可,按位或运算 SqlBulkC ...

  9. inserted触发器,一张表插入数据时,同时向另外一张表插入数据

    有时候,一个服务器上有多个数据库,需要向其中一个数据库的表中插入数据时, 同时向另外一个数据的表里插入数据. 可以利用触发器和同义词(建立同义词的方法省略), 在一个数据库的表里插入数据时,同时向另外 ...

随机推荐

  1. 2015.05.18,外语,学习笔记-《Word Power Made Easy》 03 “如何谈论不同从业者”

    Prefix Person,nous,etc. Practice,etc. Adjective psyche 精神 psychic ['saikik] adj.精神的n.灵媒 -logos 科研 ps ...

  2. Windows远程桌面和360

    Windows的远程桌面输错了一次密码, 然后就怎么都连接不上了, 查了半天发现 傻缺360会默认屏蔽Windows的远程桌面和数据库连接..... 大家没事都卸载了360吧

  3. 备份IIS

    备份IIS,这里实质指的是备份IIS配置.如果要备份IIS部署的网站的话,直接Copy目录就行了. 备份IIS配置其实和备份系统含义差不多,为了方便系统或者IIS出现故障后能够及时恢复到某节点上,所以 ...

  4. Java环境安装配置好了却不能运行xxx.jar程序?

    1,检查Java环境是否已安装或配置成功. WIN+R → cmd → java -version,查看是否可以读取到Java版本信息,如果读取不到,说明Java环境安装或配置有问题,重新装一下. 2 ...

  5. PHP邮件发送库:Swiftmailer

    Swiftmailer需要PHP 7.0或更高版本,(proc_*函数可用.) 安装 composer require "swiftmailer/swiftmailer:^6.0" ...

  6. SpringBoot(九) ElasticSearch 全文检索

    ElasticSearch ​ ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口.Elasticsearch是用 ...

  7. 浅谈javascript的面向对象思想

    面向对象的三大基本特性 封装(把相关的信息(无论数据或方法)存储在对象中的能力) 继承(由另一个类(或多个类)得来类的属性和方法的能力) 多态(一个对象在不同情况下的多种形态) 定义类或对象 第一种: ...

  8. NGUI 按钮点击事件的两种绑定形式

    面板属性栏绑定 写一个脚本,定义一个Public的方法 Notify中选择物体时,选中自己 然后就可以选择通知到写的那个脚本的里边的public方法 代码绑定 创建一个代码文件,挂载到按钮对象上 代码 ...

  9. 学习ZBrush到底需不需要用数位板?

    在学习ZBrush时,要控制下笔的力度,而这一点是鼠标办不到的.这时就需要拥有一块手绘板.手绘板可以控制笔刷的力度. 在雕刻之前,要先来了解CG设计领域广泛应用的硬件产品—数位板,如图所示. 数位板又 ...

  10. nginx上搭建https

    nginx上配置https的条件: 1.SSL证书和服务器私钥文件 2.nginx支持SSL模块 一.获取SSL证书 网上有提供权威认证的SSL证书的网站,但多数是收费的,而且不便宜.在正式的生产环境 ...