zoukankan      html  css  js  c++  java
  • QStandardItemModel的data线程安全(在插入数据时,临时禁止sizeHint去读model中的data)

    版权声明:本文为博主原创文章,欢迎转载,转载请注明出处 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

  • 相关阅读:
    Installshield Basic msi 禁用控制面板中添加删除应用
    js location.search
    c# 中关于office引用释放 技巧
    Installshield2016 condition
    bat script 点滴
    Installshield 2015 实现检测某安装文件是否存在并运行安装
    (八)基本概念列表
    (七)PM法律法规、文档配置、需求管理知识
    (六)PM项目沟通、风险、采购管理
    (五)PM项目质量管理与人力资源管理
  • 原文地址:https://www.cnblogs.com/findumars/p/9525457.html
Copyright © 2011-2022 走看看