2012-08-01 120 views
3

這裏什麼我有:QSortFilterProxyModel與QStandardItemModel後appendRow不工作

  • 一個QTreeView部件(*);
  • 源模型MainModelQStandardItemModel繼承。沒有虛擬data() const方法重新實現;
  • 代理MainFilterProxyModelQSortFilterProxyModel繼承;

樹:

[PERIOD 1] 
    [CHILD 1] 
    [CHILD 2] 
     [SUBCHILD 2.1] 
     ... 
    [CHILD N] 
[PERIOD 2] 
... 
[PERIOD N] 

所以主要的問題是當我嘗試添加兒童行像(**)的代碼做。過濾器代理模型在將文檔添加到源模型後,不知道有關新行,並且沒有在樹上顯示它。

我確定當appendRow方法完成他的工作時,代理沒有從QStandardItemModel獲得信號,因此代理無法過濾新行,並且沒有使其可見。

任何幫助?

謝謝。

PS:如果我關掉代理,一切附加就好了。但問題不在於代理。代理只是沒有得到關於新行追加到主源模型中的信號...


(*)這裏是QTreeView

MainView::MainView(QWidget* parent /* = 0 */) : QTreeView(parent) 
{ 
    if(!model_) 
    { 
      model_ = new MainModel(this); 
    } 

    if(!proxy_) 
    { 
      proxy_ = new MainFilterProxyModel(this); 
      proxy_->setDynamicSortFilter(true); 
      proxy_->setSourceModel(model_); 

      setModel(proxy_); 
    } 
} 

(**) 這裏是我的附加功能

void MainModel::addRow(const DocumentPtr& document, QStandardItem* parentItem) 
{ 
    assert(document); 

    QList< QStandardItem* > items; 
    items << (new QStandardItem); 
    items << (new QStandardItem); 
    items << (new QStandardItem); 
    items << (new QStandardItem); 
    items << (new QStandardItem); 
    items << (new QStandardItem); 
    items << (new QStandardItem); 

    updateRow(document, items); 

    if(!parentItem) 
    { 
      BOOST_FOREACH(const TimePeriod& period, TimePeriod::all()) 
      { 
       if(period.contains(QDateTime::fromTime_t(document->creationDate()))) 
       { 
        QStandardItem* periodItem = itemByPeriod(period); 
        Q_ASSERT(periodItem); 

        periodItem->appendRow(items); 

        break; 
       } 
      } 
    } 
    else 
    { 
      parentItem->appendRow(items); 
    } 
} 
+1

在示例中,您不是將項目附加到模型,而是以您以示例中不可見的方式獲取的QStandardItems。你能否簡化你的代碼,使它看起來完全並且仍然是可重現的故障? – 2012-08-01 15:34:41

+0

@vtmarvin我真的不明白我必須做什麼,但我把源文件放在這裏:http://pastebin.com/RMLqHZhS希望有所幫助! – mosg 2012-08-01 16:00:50

+0

好吧,如果你甚至不顯示MainFilterProxyModel的代碼,我們應該怎麼看它爲什麼沒有得到信號? – nus 2012-08-04 03:12:11

回答

0

建模的基類是QAbstractItemModel。最好使用抽象類的方法來做你想做的事。 QStandardItemModel是一個簡單實現的QAbstractItemModel抽象方法和大多數的QStandardItemModel新方法被重新實現的抽象函數使用。下面是一個代碼添加項目和子項目使用抽象類的方法:

QAbstractItemModel * pModel = new QStandardItemModel(parent); 

int nRows = pModel->rowCount(); 
pModel->insertRow(nRows); // this will emit rowsAboutToBeInserted() and rowsInserted() signals 
pModel->insertColumn(0); // this will emit columnsAboutToBeInserted() and columnsInserted() signals 
const QModelIndex indexFirstItem = pModel->index(nRows, 0); 
pModel->setData(indexFirstItem, "Item text"); // this will emit dataChanged() signal 
int nChildRows = pModel->rowCount(indexFirstItem); 
pModel->insertRow(nChildRows, indexFirstItem); // this will emit rowsInserted() 
pModel->insertColumn(0, indexFirstItem); // we also need to do this for the item's children 
const QModelIndex indexChild = pModel->index(nChildRows, 0, indexFirstItem); 
pModel->setData(indexChild, "Child item text"); 

如果我們試圖做同樣的使用QStandardItemModel方法它看起來像:

QStandardItemModel *pModel = new QStandardItemModel(parent); 
QStandardItem *pItem = new QStandardItem("Item text"); 
pItem->appendRow(new QStandardItem); // pItem is not yet added to pModel and rowsInserted won't be emitted 
pModel->appendRow(pItem); // this will probably emit rowsInserted() signal but since we set tha text of the item when creating the pItem the dataChanged() signal won't be emitted. 

所以,如果你pItem->appendRow()到加分項目,如果pItem尚未添加到模型中,你可能不會得到rowsInserted()信號,因此,代理模式將不另行通知。從我的經驗來看,第一種方法效果更好,並且更強大,但您需要編寫幾行額外的行。直接使用QStandardItemModel方法通常會以丟失信號或其他令人頭疼的方式結束。所有你需要看的是QAbstractItemModelQModelIndex單證。