C++ 在QTreeView/QStandardItem上跟踪对象的正确方法是什么
我有一个C++ 在QTreeView/QStandardItem上跟踪对象的正确方法是什么,c++,qt,object,qtreeview,qstandarditem,C++,Qt,Object,Qtreeview,Qstandarditem,我有一个QTreeView,它在根节点下有三个分支 QTreeView treeView_4 = new QTreeView(tab_10); QStandardItemModel standardModel = new QStandardItemModel ; QStandardItem *rootNode = standardModel->invisibleRootItem(); QStandardItem Group1Item = new QStandardItem("Group
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 IPaddress
和QString 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 mObject
我为每个小组使用QMap
进行跟踪所做的工作
QMap<QString, QString> group1MapList;
QMap<QString, QString> group2MapList;
QMap<QString, QString> group3MapList;
或
int索引=0;
对它进行迭代器;
for(it=group1MapList.begin();it!=group1MapList.end();it++){
if(it.value()==IPAddressToRemove){
group1MapList.remove(IPAddressToRemove);
Group1Item->removeRow(索引);
打破
}
索引++;
}
我注意到QMap
(以及QHash
)并没有按添加的顺序存储实体
是否有任何特殊的类来跟踪我需要的QS标准项,或者我应该使用QVector或其他什么
由于我有两个属性:IPaddr
和Name
,我是否需要两个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;
}
};
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;
}
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( );
}
父方法应返回给定节点的父节点的de索引
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;
}
模型实现完成后,我们只需将数据发送到模型并链接模型和视图:
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 );
QTreeView*treeView_4=新的QTreeView(选项卡10);
CustomModel*model=新的CustomModel(本);
std::vector>数据;
数据。推回(std::make_pair(“node1”);
数据。推回(std::make_pair(“node2”);
模型->设置组(“组1”,数据);
数据。推回(std::make_pair(“node3”);
模型->设置组(“第2组”,数据);
treeView4->setModel(model);
但OP询问了与QTreeView一起工作的QStandardItemModel,不是吗?
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;
}
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( );
}
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 );