QtQuick - 使TableView在其模型更改后更新其rowCount

时间:2016-07-08 10:04:39

标签: qt qml qtquick2 qtquickcontrols qt5.5

我有一个TableView,我想在它创建后动态填充 - 即我从我的c ++应用程序中读取了一个字符串列表,我想将其设置为TableView的模型。我使用ListModel,我在TableView的Component.onCompleted中没有遇到任何问题。但是,在加载后,我还想从列表中选择某个项目作为默认选项。问题是即使ListModel包含所有数据,TableView的rowCount属性也不会更新,所以当我调用tableView.selection.select(indexOfTheDefaultItem)时,我收到警告“TableViewSelection:index超出范围”。 我已经尝试发出ListModel.dataChanged()信号并在那里处理初始选择,但这没有帮助,我也尝试在所有其他信号(onLayoutChanged,onModelChanged ......)上做到这一点我可以找到但没有结果。如果我在第一次尝试失败后重新加载我的数据,它会起作用,因为第一次尝试时已有一些行,因此选择不会超出范围。所以似乎唯一的问题是rowCount没有更新,直到对我来说为时已晚(可能是在组件被渲染之后?)。

所以最终的问题是 - 是否有一些信号在rowCount更新之后被激活,我可以做出反应? 我已经看到一些解决方案涉及在应用程序的c ++端创建列表并使用beginInsertRows()和endInsertRows(),但这些显然不是ListView的函数,我宁愿将代码保存在qml中。 以下是我的解决方案现在的样子:

ListModel
{
    id:listModel
}
TableView
{
    id: tableView
    selectionMode:SelectionMode.SingleSelection 
    model: listModel
    TableViewColumn
    {
         role: "myRole"
         title: "myTitle"
    }
    onModelChanged // or Connections{target:listModel onDataChanged .... } or onAnythingThatWillWorkPlease:
    {
        if (tableView.rowCount > 0) // this prevents the "index out of range" warning, but does not really solve the problem
        {
            var defaultEntityIndex = 5;
            tableView.currentRow = defaultEntityIndex; // when I don't call this, the code in the onSelectionChanged below has "null pointer" exception, i.e. I presume the currentRow stays at the initial -1 - hence this "hack"
            tableView.selection.select(defaultEntityIndex);
        }
    }
    Connections
    {
        target: tableView.selection
        onSelectionChanged : 
        {
            if (tableView.currentRow >= 0)
                myC++Class.selectedThing = listModel.get(tableView.currentRow).role;
         }
    }
}
function initList()
{
    var vals = myC++Class.getTheListWithData();
    for(var i =0; i<vals.length; i++)
    {
        listModel.append({role: vals[i]});
    }
    tableView.model = listModel // I just tried to do this to trigger the modelChanged signal
    listModel.dataChanged(0, vals.length - 1);
}
Component.onCompleted:
{
    initList();
}
Connections // this is to re-fresh the tableView when my data changes
{
    target: myC++class
    onDataChanged: // my custom signal
    {
        initList();
    }
}

当前的行为是:我用这个代码打开窗口,listView填充了从getTheListWithData方法读取的字符串,但没有选择任何内容。然后,当我重新加载数据(有一个按钮)时,再次调用initList,这要归功于代码示例末尾的连接,这次它选择了所需的行。

1 个答案:

答案 0 :(得分:1)

正如Velkan在评论中指出的那样,解决方案是简单地使用onRowCountChanged信号,然后按预期工作。以下是我的完整代码。

eg: Search Text: will Burrou
Then the search result show the following result

再次感谢Velkan。

唯一的,相当复杂的问题是,我希望TableView在自动选择时向下滚动到默认元素,以便用户知道此默认选择已发生。 positionViewAtRow函数应该这样做,但不是。我找到了一些其他人有同样问题的帖子,但到目前为止他们的解决方案都没有对我有用。但是这对我的研究或最坏情况下的另一个问题来说是一个问题:)如果我找到解决方案,我会更新这个答案。

相关问题