簡體   English   中英

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

[英]QtQuick - make TableView update its rowCount after its model has changed

我有一個TableView,要在創建后動態填充它-即,我從C ++應用程序中讀取了一個字符串列表,我希望將其設置為TableView的模型。 我為此使用了一個ListModel,我從TableView的Component.onCompleted中完全沒有問題。 但是,加載后,我還想從列表中選擇某些項目作為默認選項。 問題是,即使ListModel包含所有數據,TableView的rowCount屬性也不會更新,因此當我調用tableView.selection.select(indexOfTheDefaultItem) ,會收到警告“ TableViewSelection:索引超出范圍”。 我嘗試發出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,這一次它選擇了所需的行。

正如Velkan在評論中指出的那樣,解決方案是只使用onRowCountChanged信號,然后按預期工作。 下面是我的完整代碼。

ListModel
{
    id:listModel
}
TableView
{
    id: tableView
    selectionMode:SelectionMode.SingleSelection 
    model: listModel
    TableViewColumn
    {
        role: "myRole"
        title: "myTitle"
    }
    onRowCountChanged:
    {
        if (rowCount > 0) 
        {
            var defaultEntityIndex = 0;
            for (var i = 0; i < rowCount; i++)
            {
                if (model.get(i).role == qsTr("NameOfTheDefaultItem"))
                    defaultEntityIndex = i;
            }
            // select the default item and also set it as current so that it is highlighted
            currentRow = defaultEntityIndex
            selection.select(defaultEntityIndex)
            // move the view to the item so that the user knows that something got selected without his input....though this function actually does not seem to be working
            positionViewAtRow(defaultEntityIndex, ListView.Beginning)
            focus = true     
        }
    }
    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]});
    }
    // the lines that were here in the original post are (as expected) not needed
}
Component.onCompleted:
{
    initList();
}
Connections // this is to re-fresh the tableView when my data changes
{
    target: myC++class
    onDataChanged: initList();
}

再次感謝您Velkan。

唯一的外觀問題是,我希望TableView在自動選擇默認元素時向下滾動到默認元素,以便用戶知道此默認選擇已發生。 positionViewAtRow函數應該執行此操作,但不執行此操作。 我發現其他人也有相同問題的帖子,但到目前為止,他們的解決方案都沒有對我有用。 但這是我個人進行更多研究的問題,或者在最壞的情況下,這是另一個SO問題:)如果找到解決方案,我將更新此答案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM