2

QTreeViewルートノードの下に 3 つのブランチがある

QTreeView treeView_4 = new QTreeView(tab_10);
QStandardItemModel standardModel = new QStandardItemModel ;
QStandardItem *rootNode = standardModel->invisibleRootItem();

QStandardItem Group1Item =  new QStandardItem("Group 1");
QStandardItem Group2Item =  new QStandardItem("Group 2");
QStandardItem Group3Item =  new QStandardItem("Group 3");

rootNode->appendRow(Group1Item);
rootNode->appendRow(Group2Item);
rootNode->appendRow(Group3Item);

作成時に Group1/2/3 の下にいくつかのオブジェクトをリストしたいと考えています。オブジェクトのプロパティが変更されたら、それらをあるグループから別のグループに移動したい (ステータスの変更など)。オブジェクトには、QTreeView にとって興味深い 2 つのプロパティがあります:QString IPaddressQString Name. (どちらかを QtreeView に表示したい)

それを行うための最良/適切な方法は何ですか?

class Object : public QObject
{
    Q_OBJECT
public:
//.... some properties, get and set functions, etc.
    QStandardItem *NodeItemIP;
    QStandardItem *NodeItemName;
private:
   QString Name;
   QString IPaddr;
///....
}

オブジェクトをに保存しますQVectorQVector<Object*> mObject

QMap各グループを追跡するために使用したこと

QMap<QString, QString> group1MapList;
QMap<QString, QString> group2MapList;
QMap<QString, QString> group3MapList;

そして、insertそれらQmapがに追加されたときにQStandardItem

group1MapList.insert(mObject[1]->getName(), mObject[1]->getIPaddr());
Group1Item.appendRow(mObject[1]->NodeItemIP);

また

int index = 0;
QMap<QString, QString>::Iterator it;
for (it=group1MapList.begin(); it != group1MapList.end(); it++){
      if(it.value() == IPAddrToRemove){
      group1MapList.remove(IPAddrToRemove);
      Group1Item->removeRow(index);
      break;
   }
  index++;
}

エンティティが追加された順序で保存されないことQMapに気付きました。QHash

必要に応じて QStandardItems を追跡する特別なクラスはありますか、またはQVectorなどを使用する必要がありますか?

IPaddrとの 2 つのプロパティがあるので、それらを追跡するNameには 2 つの が必要ですか、それとも両方を処理できるものがありますか?QVector

注: コピー+貼り付け/編集エラーがない場合は、上記のコード スニペットの構文で問題ありません。

4

1 に答える 1

2

を使用している場合QTreeView、データ ツリーをモデル化するためにカスタム データ構造を作成する必要があるかもしれません。このようなもの:

struct ModelItem
{
  QString groupName;
  QString name;
  QString IPaddr;
  ModelItem* parent;
  std::vector< ModelItem* > childs;

  ModelItem( const QString& a_name )
    : name( a_name ),
      parent( nullptr )
  { }

  ~ModelItem( )
  {
    for ( auto it = childs.begin( ); it != childs.end( ); ++it )
      delete *it;
  }

  void AddChild( ModelItem* children )
  {
    childs.push_back( children );
    children->parent = this;
  }
};

もちろん、サブクラス化する必要がありますQAbstractItemModel:

class CustomModel : public QAbstractItemModel
{
    Q_OBJECT

  public:

    CustomModel( QObject* parent = nullptr );

    ~CustomModel( );

    int columnCount( const QModelIndex& parent ) const override;

    int rowCount( const QModelIndex& parent ) const override;

    QVariant data( const QModelIndex& index,
                   int role = Qt::DisplayRole ) const override;

    QModelIndex index ( int row,
                        int column,
                        const QModelIndex& parent ) const override;

    QModelIndex parent( const QModelIndex & index ) const override;

    void SetGroup( const QString& groupName,
                   const std::vector< std::pair< QString, QString > >& items );

    void ResetModel( );

  private:

    ModelItem rootNode;

};

columnCount および rowCount メソッドは、モデルの列/行の数を返します。

int CustomModel::columnCount( const QModelIndex& /* parent */ ) const
{
  return 1;
}

int CustomModel::rowCount( const QModelIndex& parent ) const
{

  int to_return;

  if ( parent.isValid( ) )
  {
    ModelItem* node = static_cast< ModelItem* >( parent.internalPointer( ) );
    to_return = node->childs.size( );
  }
  else
    to_return = rootNode.childs.size( );

  return to_return;
}

data メソッドは、モデルのコンテンツを返します。

QVariant CustomModel::data( const QModelIndex& index,
                            int role ) const
{
  QVariant to_return;

  if ( index.isValid( ) ) // if not valid, current index is root node
  {
    switch ( role )
    {
      case Qt::DisplayRole: // you can manage other roles to enrich the view
      {
        ModelItem* node = static_cast< ModelItem* >( index.internalPointer( ) );
        to_return = node->name;
        break;
      }
    }
  }

  return to_return;
}

インデックスは、指定されたノードの適切な作成を行いQModelIndexます:

QModelIndex CustomModel::index ( int row,
                                 int column,
                                 const QModelIndex& parent ) const
{
  QModelIndex to_return;

  if ( ( row >= 0 && row < rowCount( parent ) )
    && ( column >= 0 && column <= columnCount( parent ) ) )
  {
    if ( parent.isValid( ) )
    {
      ModelItem* item = static_cast< ModelItem* >( parent.internalPointer( ) );
      to_return = createIndex( row, column, item->childs.at( row ) );
    }
    else
    {
      to_return = createIndex( row, column, rootNode.childs.at( row ) );
    }
  }

  return to_return;
}

親メソッドは、指定されたノードの親のインデックスを返します

QModelIndex CustomModel::parent( const QModelIndex & index ) const
{
  QModelIndex to_return;

  if ( index.isValid( ) )
  {
    ModelItem* node = static_cast< ModelItem* >( index.internalPointer( ) );
    ModelItem* parent = node->parent;
    ModelItem* parent2 = parent->parent;

    if ( parent2 ) // node->parent can be root node
    {
      auto it = std::find_if( parent2->childs.begin( ), parent2->childs.end( ),
                              [&]( ModelItem* child ){ return child == parent; } );

      if ( it != parent2->childs.end( ) )
      {
        int row = std::distance( parent2->childs.begin( ), it );
        to_return = createIndex( row, 0, parent );
      }
    }
  }

  return to_return;
}

次のメソッド: SetGroup。このメソッドを使用して、モデルにデータを追加できます。

void CustomModel::SetGroup( const QString& groupName,
                            const std::vector< std::pair< QString, QString > >& items )
{
  // Notify to view that we will insert a new group
  beginInsertRows( QModelIndex( ), rootNode.childs.size( ), rootNode.childs.size( ) );

  ModelItem* groupNode = new ModelItem( groupName );
  rootNode.AddChild( groupNode );

  for ( auto it = items.begin( ); it != items.end( ); ++it )
  {
    ModelItem* node = new ModelItem( it->first );
    node->name = it->first;
    node->IPaddr = it->second;
    groupNode->AddChild( node );
  }

  endInsertRows( );
}

ResetModel メソッドは単にビューをきれいにします:

void CustomModel::ResetModel( )
{
  beginResetModel( );
  rootNode= ModelItem( "root" );
  endResetModel( );
}

モデルの実装が完了したら、データをモデルに送信し、モデルとビューをリンクするだけです。

QTreeView* treeView_4 = new QTreeView( tab_10 );
CustomModel* model = new CustomModel( this );

std::vector< std::pair< QString, QString > > data;
data.push_back( std::make_pair( "node1", "" ) );
data.push_back( std::make_pair( "node2", "" ) );

model->SetGroup( "Group 1", data );

data.push_back( std::make_pair( "node3", "" ) );
model->SetGroup( "Group 2", data );

treeView4->setModel( model );
于 2014-07-09T10:28:17.613 に答える