gpt4 book ai didi

c++ - 在 QTreeView/QStandardItem 上保持跟踪对象的正确方法是什么

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:22:04 25 4
gpt4 key购买 nike

我有一个 QTreeView在一个根节点下有三个分支

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 感兴趣的属性: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;
///....
}

我将对象存储在 QVector 中: QVector<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 还是其他任何东西?

因为我有两个属性:IPaddrName , 我需要两个 QVector是跟踪它们还是可以同时处理它们?

注意:如果没有复制+粘贴/编辑错误,那么上面的代码片段的语法应该没问题。

最佳答案

如果您正在使用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;
}

数据方法应返回模型的内容:

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 方法简单地清理 View :

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

模型实现完成后,我们只需要将数据发送到模型并链接模型和 View :

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

关于c++ - 在 QTreeView/QStandardItem 上保持跟踪对象的正确方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24649520/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com