3

ここに私が持っているもの:

  • ウィジェットQTreeView(*);
  • ソースモデルMainModelはから継承しQStandardItemModelます。data() const再実装された仮想メソッドはありません。
  • プロキシは;MainFilterProxyModelから継承します。QSortFilterProxyModel

ツリー:

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

したがって、主な問題は、 (**)コードのようにCHILD行を追加しようとしたときに発生します。ドキュメントがソースモデルに追加された後のフィルタープロキシモデルは、新しい行を認識せず、ツリーに表示されませんでした。

QStandardItemModelメソッドが彼の仕事をするときからプロキシがシグナルを受け取らなかったと確信しているので、プロキシはappendRow新しい行をフィルタリングできず、それを表示しませんでした。

何か助けはありますか?

ありがとう。

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 );
     }
}
4

1 に答える 1

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ドキュメントだけです。

于 2013-04-30T17:37:06.367 に答える