c++ - 异步 Qt 模型加载到 QML GridView

标签 c++ qt gridview asynchronous qml

我在将 QAbstractListModel 项目异步加载到 QML GridView 时遇到问题。当我执行将项目加载到模型的方法时,我必须等待每个项目都已加载。如何动态获取项目(即一个接一个)?

我有相当大的模型对象,有 17 个字段(QStringQStringList)。对象包含在自定义模型中:

class MyListModel : public QAbstractListModel 
{
    Q_OBJECT
public:
    enum ListItemRole {
        IdRole  = Qt::UserRole,
        VisualIndexRole,
        NameRole,
        ...
    };

    MyListModel(QObject *parent = 0) 
        : QAbstractListModel(parent)
    {
    }
    int rowCount(const QModelIndex &parent) const
    {
        Q_UNUSED(parent)
        return m_data.size();
    }
    QVariant data(const QModelIndex &index, int role) const
    {
        if( !index.isValid() || index.row() >= m_data.size() || index.row() < 0)
            return QVariant();

        switch(role) {
        case NameRole:
            return QVariant(m_data.at(index.row())->name());

        ...
        (rest of the roles)
        ...
        }
    }


    QHash<int, QByteArray> roleNames() const
    {
        QHash<int, QByteArray> roles;
        roles[IdRole] = "folderName";
        ...
        return roles;

    }

private:
    QList<Item*> m_data;

}

我正在通过附加方法向模型中插入项目:

void append(Item *item)
{
    beginInsertRows(QModelIndex(), m_data.size(), m_data.size());
    m_data.append(item);
    endInsertRows();
}

项目是在其他函数的循环中创建的。此函数从 3 个 JSON 文件加载数据。加载 50 个项目大约需要 2 秒。

在此列表模型之上,有两个 QSortFilterProxyModel 负责排序和过滤 View 。过滤模型注册为 QML 类型并在 GridView 中使用。

我尝试过的:

  • 对创建项目的函数使用 QtConcurrent::run() 方法 - 失败( View 未在每个项目后刷新)
  • 为每个列表项制作QThread,并用Worker 类加载它 - 失败(应用程序崩溃和奇怪的行为,即空项目,代表之间的空白和 -与第一点一样 - 不是异步)
  • 将模型移动到 QThread 并在 Worker 类中使用项目创建循环 - 部分成功(当我使用 QCoreApplication::processEvents(QEventLoop::AllEvents,100 ); 作为 sleep 函数,我可以一项一项地获取,但存在严重的性能问题,而且 - 正如我所读 - 这不是好的方法)

我的问题是否有任何可能的解决方法?

最佳答案

看看this question .我相信你有同样的问题。异步模型加载的问题在于您可以从单独的线程加载模型数据,即从非 GUI 线程调用 append(Item *item) 函数。但是您必须确保 beginInsertRows(...)endInsertRows() 函数都是从主 GUI 线程运行的。链接的问题解释了如何做到这一点。

关于c++ - 异步 Qt 模型加载到 QML GridView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34905146/

相关文章:

javascript - 如何使用jquery或javascript获取gridview中的DataKey值?请在回答之前先阅读代码

android - 如何将图像从 JSON 获取到 Android 中的 GridView 中?

c++ - move lambda : once you've move-captured a move-only type, 如何使用 lambda?

c++ - 使用 strlen 在 winapi 中获取字符串长度

c++ - 找不到我的错误-抽象错误

c++ - 在 QGraphicsItem 上绘制尺寸

c++ - QPainterPath QTransform::map

android - Android 中的 GridView ListSelector 重点?

c++ - 非命名空间范围的显式特化

c - Qt多线程应用程序卡住并且多个线程等待相同的互斥体