使用 C++ 使用对象构建自定义 QTreeView
Building A Custom QTreeView with objects using C++
好的,所以我对这个 post 中包含的所有主题有点菜鸟。 C++ 新手和 Qt 新手。话虽这么说,我已经阅读了大量有关该主题的文章,并且已经为此工作了很长一段时间。也许我没有正确地解决这个问题,或者我可能完全走错了方向。请帮助并建议我应该如何处理这个问题!
我正在构建基于以下 class 结构的 QtreeView:(仅显示重要成员)
Class ScenarioManager // singleton
{
Qvector<object_A*> *AllObjectA's
}
Class Object_A
{
QString name
Qvector<double> numSet // 3 values inside
Qvector<double> numSet2 // 2 values inside.
QString type
Qvector<Object_B*> AllObjectB's //Object_B is an interface class with
//purely virtual functions
}
Class Object_C : Object_B
{
QString name
bool isTypeObjectC
Object_F* exact
}
Class Object_D : Object_B
{
String name
bool isTypeObjectC
Object_F* min
Object_F* max
QVector<Object_F*> AllObjectF's // setOfAllMins/Maxes that subdivide the
// region between min and max.
}
Class Object_F
{
double value
}
我已经按照创建树视图的示例进行操作,可以在此处找到:
http://doc.qt.io/qt-5/qtwidgets-itemviews-simpletreemodel-example.html
并成功制作出我想要的视图,如下所示:
|__name__|__type__|__f-range__|__allobjectf_| // header data
|
|Object_A1-name __Object_A1_Type // under name and type fields
| |
| AllObjectC's // under name
| | |
| | Object_C1_name // under name
| | Object_C2_name
| | |______exact.value // under f-range
| AllObjectD's
| |
| Object_D1_name
| Object_D2_name
| |_____min.value '-' max.value // under f-range
| |__AllObjectF[0].min '-' AllObjectF[0].max//under allObjF
| |__AllObjectF[1].min '-' AllObjectF[1].max
| |__AllObjectF[2].min '-' AllObjectF[2].max
|
|Object_A2-name __Object_A2_Type....(repeat)
我的问题是我仍然需要能够完成另外 2 个任务,这些任务在我的一生中似乎无法使用该示例完成(在 link posted ) 作为模板。
我的代码几乎完全相同地模仿了 link 中的示例!模型 class 遍历我的 scenariomanager 成员向量,构造树项,并且以与 SetupModelData 函数几乎相同的方式粗略地构建一个带有字符串的 TreeView。
一切都很好,除了我需要做以下事情。
- select树中的一个项目,点击删除按钮
- 完成后,需要从树视图(及其子视图)中删除该项目
- 并且该项目需要从原始方案管理器中完全删除。
- select 树中的一个项目,并能够向该对象添加适当的子项。
- 需要在树视图中显示
- 并且需要添加到场景管理器的适当位置
我这辈子都不知道该怎么做,我尝试了一大堆想法,但就是没能成功。解决这个问题的最佳方法是什么?
有什么方法可以从树视图中获取更多的 QVarient 字符串吗?是否有可能获得指向创建树的实际树节点的指针?如果我能做到这一点,我只需修改要创建的树节点,并使用指向创建它们的场景管理器对象的指针并操纵路由。
但是最好的方法是什么?我无法找到任何具体概述我正在努力完成的事情。
提前感谢您的帮助!
您使用的是什么树模型class?
我还是不能评论:(所以我才在回答区发这个评论,希望大家不要介意。
基本上,您的 treemodel-item class 将需要支持删除和附加项目的功能。
例如
void ItemClass::insertChild(int row, itemClass *item){
item->m_parent = this;
m_children.insert(row, item);
}
因此,如果您有一个项目,并且想在第 5 行向其添加另一个项目,例如
item->insertChild(5, anotherItem)
函数中的第一行将使 item 成为 anotherItem 的父项,然后在本例中将 anotherItem 添加到第 5 行的 item 的子项列表中
要获取指向当前所选项目的指针,我会这样做:
QVariant TreeModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
if (role != Qt::DisplayRole && role != Qt::EditRole)
return QVariant();
TreeItem *item = getItem(index);
pointervariable = item; <<== pointervariable is inside your modelclass
return item->data(index.column());
}
我确实设法完成了我需要完成的工作,尽管我仍然坚信这不是最好的方法。欢迎提出更好的建议!!
最终我修改了我的树节点 class 以拥有一个成员字段:
QObject* dataSource;
此指针是在为每个树项创建模型时设置的。然后您可以通过这样的方法访问创建模型的原始数据源
QModelIndex anIndex = ui->treeView->currentIndex();
if(anIndex.isValid())
{
STreeItem *item = static_cast<STreeItem*>(anIndex.internalPointer());
ObjectType* obj = static_cast<ObjectType*>(item->getDataSourcePointer());
}
我希望这对处于类似情况的其他人有所帮助,感谢您的想法和指导!
好的,所以我对这个 post 中包含的所有主题有点菜鸟。 C++ 新手和 Qt 新手。话虽这么说,我已经阅读了大量有关该主题的文章,并且已经为此工作了很长一段时间。也许我没有正确地解决这个问题,或者我可能完全走错了方向。请帮助并建议我应该如何处理这个问题!
我正在构建基于以下 class 结构的 QtreeView:(仅显示重要成员)
Class ScenarioManager // singleton
{
Qvector<object_A*> *AllObjectA's
}
Class Object_A
{
QString name
Qvector<double> numSet // 3 values inside
Qvector<double> numSet2 // 2 values inside.
QString type
Qvector<Object_B*> AllObjectB's //Object_B is an interface class with
//purely virtual functions
}
Class Object_C : Object_B
{
QString name
bool isTypeObjectC
Object_F* exact
}
Class Object_D : Object_B
{
String name
bool isTypeObjectC
Object_F* min
Object_F* max
QVector<Object_F*> AllObjectF's // setOfAllMins/Maxes that subdivide the
// region between min and max.
}
Class Object_F
{
double value
}
我已经按照创建树视图的示例进行操作,可以在此处找到: http://doc.qt.io/qt-5/qtwidgets-itemviews-simpletreemodel-example.html
并成功制作出我想要的视图,如下所示:
|__name__|__type__|__f-range__|__allobjectf_| // header data
|
|Object_A1-name __Object_A1_Type // under name and type fields
| |
| AllObjectC's // under name
| | |
| | Object_C1_name // under name
| | Object_C2_name
| | |______exact.value // under f-range
| AllObjectD's
| |
| Object_D1_name
| Object_D2_name
| |_____min.value '-' max.value // under f-range
| |__AllObjectF[0].min '-' AllObjectF[0].max//under allObjF
| |__AllObjectF[1].min '-' AllObjectF[1].max
| |__AllObjectF[2].min '-' AllObjectF[2].max
|
|Object_A2-name __Object_A2_Type....(repeat)
我的问题是我仍然需要能够完成另外 2 个任务,这些任务在我的一生中似乎无法使用该示例完成(在 link posted ) 作为模板。
我的代码几乎完全相同地模仿了 link 中的示例!模型 class 遍历我的 scenariomanager 成员向量,构造树项,并且以与 SetupModelData 函数几乎相同的方式粗略地构建一个带有字符串的 TreeView。
一切都很好,除了我需要做以下事情。
- select树中的一个项目,点击删除按钮
- 完成后,需要从树视图(及其子视图)中删除该项目
- 并且该项目需要从原始方案管理器中完全删除。
- select 树中的一个项目,并能够向该对象添加适当的子项。
- 需要在树视图中显示
- 并且需要添加到场景管理器的适当位置
我这辈子都不知道该怎么做,我尝试了一大堆想法,但就是没能成功。解决这个问题的最佳方法是什么?
有什么方法可以从树视图中获取更多的 QVarient 字符串吗?是否有可能获得指向创建树的实际树节点的指针?如果我能做到这一点,我只需修改要创建的树节点,并使用指向创建它们的场景管理器对象的指针并操纵路由。
但是最好的方法是什么?我无法找到任何具体概述我正在努力完成的事情。
提前感谢您的帮助!
您使用的是什么树模型class?
我还是不能评论:(所以我才在回答区发这个评论,希望大家不要介意。
基本上,您的 treemodel-item class 将需要支持删除和附加项目的功能。
例如
void ItemClass::insertChild(int row, itemClass *item){
item->m_parent = this;
m_children.insert(row, item);
}
因此,如果您有一个项目,并且想在第 5 行向其添加另一个项目,例如
item->insertChild(5, anotherItem)
函数中的第一行将使 item 成为 anotherItem 的父项,然后在本例中将 anotherItem 添加到第 5 行的 item 的子项列表中
要获取指向当前所选项目的指针,我会这样做:
QVariant TreeModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
if (role != Qt::DisplayRole && role != Qt::EditRole)
return QVariant();
TreeItem *item = getItem(index);
pointervariable = item; <<== pointervariable is inside your modelclass
return item->data(index.column());
}
我确实设法完成了我需要完成的工作,尽管我仍然坚信这不是最好的方法。欢迎提出更好的建议!!
最终我修改了我的树节点 class 以拥有一个成员字段:
QObject* dataSource;
此指针是在为每个树项创建模型时设置的。然后您可以通过这样的方法访问创建模型的原始数据源
QModelIndex anIndex = ui->treeView->currentIndex();
if(anIndex.isValid())
{
STreeItem *item = static_cast<STreeItem*>(anIndex.internalPointer());
ObjectType* obj = static_cast<ObjectType*>(item->getDataSourcePointer());
}
我希望这对处于类似情况的其他人有所帮助,感谢您的想法和指导!