2017-04-25 63 views
0

我的QML ListView直到我用鼠标干扰它时才显示我的数据(,例如只是将它上下拖动)。之后,视图显示模型,直到它清空,然后那么我再一次需要扰乱它才能重新运作。有没有办法踢这个ListView进入工作?ListView最初没有显示数据

我在Linux 14.04上使用Qt 5.8。我的模型是QAbstractListModel的子类。我通过遵循AbstractItemModel Example来构建它。主要区别在于我的列表模型是实体的属性,而不是在中使用setContextProperty进行设置。

在SO上有几个类似的问题,关于ListView没有更新,但没有一个在开始时似乎只有一个问题。他们中的大多数涉及到OP调用dataChanged手动,而不是beforeInsertRows() & endInsertRows() - 这两种方法我打电话(见下文)。

ListView是装载了SceneLoader项目。

posted all the relevant code here,因为我是有点怀疑的我如何使用布局上我ListView(也许这就是造成的呢?也许我的等级制度被打破?我一直没能证明,虽然)。

总之,虽然,

的ListView

ListView { 
    anchors.fill: parent 
    model: sceneGraph.blobs 
    delegate: delegate 
} 

BlobModel.cpp

auto BlobModel::addBlob(const BlobPointDataPtr& data) -> void 
{ 
    // ... 

    // Each blob has a uuid 

    const auto idx = Contains(uuid); 
    if (-1 != idx) 
    { 
     blobs_[idx]->Update(data); 
     Q_EMIT dataChanged(createIndex(idx, 0), createIndex(idx, 0)); 
    } 
    else 
    { 
     beginInsertRows(QModelIndex(), rowCount(), rowCount()); 
     blobs_ << new Blob{data, id_count_}; id_count_++; 
     endInsertRows(); // responsible for the QQmlChangeSet 

     Q_EMIT dataChanged(createIndex(rowCount(), 0), createIndex(rowCount(), 0)); 
    } 
} 

而且,我的终端上,我收到消息:

QObject::connect: Cannot queue arguments of type 'QQmlChangeSet' 
(Make sure 'QQmlChangeSet' is registered using qRegisterMetaType().) 

这似乎是由endInsertRows()发出,但我不知道为什么。过去,解决方案是登记丢失的类型,例如,例如qRegisterMetaType<QQmlChangeSet*>("QQmlChangeSet");但是这似乎不是一个Qt的公共类型,并且因为所有东西都是没有它的,所以我不确定这是不是确切的问题。

+1

我已经尽你所能地测试了你的代码。为了简单起见,我用QStrings替换了Blob对象。我完全按照AbstractItemModel示例所做的那样创建了addBlob()。它为我工作得很好。 [Code Here](https://gist.github.com/anonymous/1a41d90c212c73086fe81c41374b9661) –

+0

你是如何填充模型的?我发现如果模型中存在初始数据,它就可以正常工作,问题只有在模型是空的时候才会起作用(所以在启动时或模型清空时)。感谢您查看它,我会尝试实际创建一个完整的最小例子,然后我会用你的例子中的字符串来尝试它,看看是否有任何区别。 – Matt

+0

嗯,我只是建立了一个[最小的可编译示例](https://github.com/kheaactua/listview_issue/tree/master/listview_issue),它也可以。在早上,我会再添加一点,使其更接近我的原始代码,以查看问题开始的位置(然后删除此评论) – Matt

回答

0

正如在评论中指出的那样,问题是我在主线程之外修改我的模型。

我的代码已设置,以便另一个线程通过直接调用addData来触发对我的模型的添加。我最小的例子无法复制这个的原因是因为在其中我使用QTimer来模拟其他线程,但QTimer也运行在主线程上。

解决方法是将我的直接调用改为addData(data)以发出信号以进行添加,从而将实际工作移回主线程。