- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我有一个 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<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
和 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;
}
};
当然,你需要继承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/
我想把 QComboBox变成 QStandardItem用于 QStandardItemModel .我一直在环顾四周,我找不到答案,有什么想法吗? 最佳答案 您不存储 QComboBox在 QSt
我正在尝试创建一个支持项目内部移动的 QTreeView 以及一种检测移动源和目标的方法。使用 QTreeWidget 时,我可以覆盖 dropEvent 并执行如下操作: void MyTreeWi
我的 Qt 版本是 5.5.1 (Linux),由于某些原因我无法升级它。 我有 QTableView(继承自 QWidget),这个 QTableView 有模型 QStandardItemMode
我目前在 QStandardItem 中有文本,它是 "mm3",现在这应该是毫米立方体。有什么方法可以使它在 View 中变为 mm^3(即上标 3)? 最佳答案 你应该使用 sup具有 super
使用 Qt4 的模型/ View 框架,我有一个显示为“Foo (38 bars)”的项目列表。我想让文本可编辑,但是当用户开始编辑时,我希望控件只显示“Foo”(名称),然后在编辑完成时恢复额外信息
如以下代码所示,当您拖放一个项目(使用 clone() 方法从 QStandardItem 子类化)时,您将获得一个 QStandardItem 而不是子类。此外,存储在类中或作为 setData 一
我有一个自定义类 ConnectionStandardItem,它是 QStandardItem 的子类。此项应包含稍后在 QSqlDatabase 中使用的服务器、用户名、密码等信息。 Connec
我在 Qt 中使用 C++ 进行编程。当我构造 QStandardItem 时,它不接受之前声明的 QString: file_content = new QString(textstream
我想要的是: Root ------ item1 | --- newItem |_____ item 2 | --- newItem
从 QStandardItem 派生时出现意外错误。我如何添加我的派生类是添加新>> C++ 类。选择基类作为 QObject,创建类后,我将 QObject 重命名为 QStandardItem。
我想知道是否可以向 QStandardItem 添加自定义类。我目前正在做这样的事情 QStandardItem* item_text= new QStandardItem(); item_text
我有一个 QTreeView(100 行)和 QStandardItemModel(10 列) 每个表格单元格都有作为 QStandardItem 插入的数据在第二列中,我需要以下掩码“0-00-00
我正在尝试显示一个图标和文本表格,以便每个项目在图标上方都有文本。 我目前正在使用 QStandardItems 与 QStandardItemModel 和 QTableView 来显示信息,但是文
我有: self.treeView = QTreeView() self.treeView.setObjectName("testView") self.treeView.setDragDropMod
使用 PyQt 5,我一直在尝试找到一种方法,使用 QStandardItemModel 和 QStandarItems 从 QTreeView 情况下的项目上的拖放操作中获取旧父级。 如果可能的话,
我想从项目中删除特定的 child ,我的父项目是常量,即。我不能用不同的父项目替换它,我必须处理我拥有的那个。子项本身有多个级别的子项。我试过了,但没用。 QStringList list; //
如果我像这样构造一个QStandardItem: item = QtGui.QStandardItem('Item Name') 当此项目添加到 QStandardItemModel 模型并在 QTr
我正在尝试使用自定义 QStandardItem 在两个 QListViews 之间进行拖放。 除了this document,我在网上找不到我需要的信息这有点帮助,但现在我被困住了。 从一个 QLi
我需要从 csv 文件中绘制图表。我为此使用了 QList。我需要获取特定列中的所有项目,例如第 4 列中的项目。这是我解析 csv 文件并写入表的方法。我需要一种方法来获取一行中的每 4 个元素。
有什么方法可以为 QStandardItemModel 中的条目分配一个唯一的键,以便我们可以检查该键的存在。如果它存在,我们得到相关的 QstandardItem ? 更新: 这是我正在尝试做的事情
我是一名优秀的程序员,十分优秀!