2017-06-21 93 views
0

我有一個QTableView,其數據模型是從我自己創建的QSortFilterProxyModel派生的類。在這個類中,我們重新實現了方法filterAcceptsRow,以便能夠根據幾個標準過濾表中的數據。我也可以通過其中的任何字段對錶格進行排序。使用QSortFilterProxyModel添加新行

當用戶單擊「創建」按鈕時會出現問題,該按鈕將在表中創建一個新的空行。如果我應用了過濾器,則不會顯示空行,因爲它不符合此過濾器,我不希望這樣做,因爲用戶必須開始強制編輯其數據。當我添加空行時,它自動根據排序標準將它自己放在它播放的位置,這是不可取的,因爲我希望它始終是在第一個位置。

任何想法如何解決這個問題?

+0

您可能會臨時禁用使用QTableView :: setSortingEnabled(false)進行排序並啓用後者。 – vahancho

回答

0

我會嘗試以下方法:

  1. 添加另一列到模型:「新項目」。該列將包含一個布爾標誌,指示該項目是否是新的,即它剛剛被用戶添加。由於該列純粹是爲了內部目的,因此它不會被視圖顯示,例如,當您設置視圖時,您需要在此列的視圖上調用setColumnHidden方法。
  2. 使用「創建」按鈕將此列中的值設置爲true以添加到模型中的新項目。
  3. 調整模型的sort方法(即覆蓋QSortFilterProxyModel的方法)始終支持將「新項目」標誌設置爲true的項目,而不考慮其他排序標準。
  4. 創建一個自定義委託的視圖(如果你沒有的話),這將繼承QStyledItemDelegate並以非常簡單的方式重新實現setModelData方法:

    void MyItemDelegate::setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) 
    { 
        QStyledItemDelegate::setModelData(editor, model, index); 
    
        MyModel * myModel = qobject_cast<MyModel*>(model); 
        myModel->clearNewFlagFromItem(index); 
    } 
    

    在這裏,你讓QStyledItemDelegate做它的事將編輯器的數據插入到模型中,但是您立即將false設置爲該項目的「新項目」標誌,從而表示該用戶已完成其創建,並且從現在開始應該使用傳統分類標準對該項目進行排序。

    在理想的世界中,您還應該考慮取消物品創建的可能性。例如,如果按下「創建」按鈕並且新行的編輯器已打開,但用戶沒有輸入任何內容並按下Enter,則應該認識到代理的內部setModelData並不是將空字符串插入模型中,而是將該項目從該模型。