我在将 QAbstractListModel
项目异步加载到 QML GridView
时遇到问题。当我执行将项目加载到模型的方法时,我必须等待每个项目都已加载。如何动态获取项目(即一个接一个)?
我有相当大的模型对象,有 17 个字段(QString
和 QStringList
)。对象包含在自定义模型中:
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/