我是靠谱客的博主 英勇豆芽,最近开发中收集的这篇文章主要介绍QStandardItemModel的data线程安全,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

在直接使用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();
}

最后

以上就是英勇豆芽为你收集整理的QStandardItemModel的data线程安全的全部内容,希望文章能够帮你解决QStandardItemModel的data线程安全所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(36)

评论列表共有 0 条评论

立即
投稿
返回
顶部