当前位置:   article > 正文

Qt 简单写一个TreeView,控制图层

Qt 简单写一个TreeView,控制图层

背景:

近期要用Qt写一个 加载渲染激光点云的小工具软件, 对于这种软件来说,首先要有一个图层树来方便控制.因而做了一个小demo来记录一下;

效果展示:

要完成的功能: 增,删,改,查,收起,以及展开的操作效果.以及对自己定义

 实现过程:

1.先定义自己的数据结构:

  1. #include <iostream>
  2. #include <list>
  3. /// <summary>
  4. /// Tree 基础图元
  5. /// </summary>
  6. class IXPloteTreeItem
  7. {
  8. public:
  9. IXPloteTreeItem();
  10. ~IXPloteTreeItem();
  11. static long XPloteNumsID;//全局的ID
  12. void SetData(const std::string& name);
  13. int GUID;
  14. std::string gName{ "" };
  15. std::shared_ptr<std::list<IXPloteTreeItem>> gChilds{ nullptr };
  16. std::string toString() const;
  17. };

2.定义TreeStandItem,来包裹自己的结构

 XPloteStandardItem.h头文件.

  1. #include <qstandarditemmodel.h>
  2. #include "IXPloteTreeItem.h"
  3. /// <summary>
  4. /// 创建自己的QstandItem 子项目.
  5. /// </summary>
  6. class XPloteStandardItem :public QStandardItem
  7. {
  8. public:
  9. using QStandardItem::QStandardItem;
  10. XPloteStandardItem() :QStandardItem() {
  11. InitData();
  12. }
  13. XPloteStandardItem(const QString& str) :QStandardItem(str)
  14. {
  15. InitData();
  16. gTreeData->gName = str.toStdString().c_str();
  17. }
  18. ~XPloteStandardItem();
  19. std::shared_ptr<IXPloteTreeItem> gTreeData{ nullptr };
  20. private:
  21. void InitData();
  22. };

 XPloteStandardItem.cpp文件

  1. #include "XPloteStandardItem.h"
  2. #include <memory>
  3. XPloteStandardItem::~XPloteStandardItem()
  4. {
  5. }
  6. void XPloteStandardItem::InitData()
  7. {
  8. if(gTreeData==nullptr) gTreeData = std::make_shared<IXPloteTreeItem>();
  9. this->setCheckable(true);
  10. this->setCheckState(Qt::Checked);
  11. this->setEditable(false);
  12. }

3.UI上面我就不写了,随便拖一个TreeView控件上去,主要是下面的关键代码以及实现过程:

 QtTree.h 类头文件

  1. /// <summary>
  2. /// 主窗体函数.
  3. /// </summary>
  4. class QtTree : public QMainWindow
  5. {
  6. Q_OBJECT
  7. public:
  8. QtTree(QWidget *parent = nullptr);
  9. ~QtTree();
  10. void InitSource();
  11. public slots:
  12. void on_treeView_customContextMenuRequested(const QPoint &pos);
  13. private:
  14. Ui::QtTreeClass ui;
  15. QMenu* menu;
  16. QStandardItemModel* model;
  17. QStandardItem* rootItem1;
  18. QStandardItem* rootItem2;
  19. };

 QtTree.cpp实现部分:

  1. #include "QtTree.h"
  2. #include <QMessageBox>
  3. QtTree::QtTree(QWidget *parent)
  4. : QMainWindow(parent)
  5. {
  6. ui.setupUi(this);
  7. InitSource();
  8. }
  9. QtTree::~QtTree()
  10. {
  11. }
  12. void PrintLog(const std::string& str)
  13. {
  14. QMessageBox::information(nullptr,"",str.c_str());
  15. }
  16. void PrintLog(QString str)
  17. {
  18. QMessageBox::information(nullptr, "", str);
  19. }
  20. void QtTree::InitSource()
  21. {
  22. ui.treeView->setContextMenuPolicy(Qt::CustomContextMenu);
  23. //添加右键菜单...
  24. QString qss = "QMenu{color:#E8E8E8;background:#4D4D4D;margin:2px;}\
  25. QMenu::item{padding:3px 20px 3px 20px;}\
  26. QMenu::indicator{width:13px;height:13px;}\
  27. QMenu::item:selected{color:#E8E8E8;border:0px solid #575757;background:#1E90FF;}\
  28. QMenu::separator{height:1px;background:#757575;}"; //设置样式表
  29. menu = new QMenu(ui.treeView);
  30. menu->setStyleSheet(qss); //给菜单设置样式
  31. QAction* a1 = new QAction(QStringLiteral("增加"));
  32. menu->addAction(a1);
  33. connect(a1, &QAction::triggered, this, [&]() {
  34. QModelIndex curIndex = ui.treeView->currentIndex();
  35. if (curIndex.isValid())
  36. {
  37. #if 0
  38. auto parentIndex = curIndex.parent();
  39. if (parentIndex.isValid())
  40. {
  41. auto parentItem = model->itemFromIndex(parentIndex);
  42. if (parentItem != nullptr)
  43. {
  44. parentItem->appendRow(new QStandardItem(QStringLiteral("城市_%1").arg(model->rowCount())));
  45. }
  46. }
  47. else
  48. {
  49. //model
  50. model->appendRow(new QStandardItem(QStringLiteral("城市_%1").arg(model->rowCount())));
  51. }
  52. #else
  53. auto curItem = model->itemFromIndex(curIndex);
  54. if (curItem != nullptr)
  55. {
  56. auto item = new XPloteStandardItem(QStringLiteral("城市_%1").arg(model->rowCount()));
  57. item->setCheckable(true);
  58. item->setCheckState(Qt::Checked);
  59. curItem->appendRow(item);
  60. }
  61. #endif // 0
  62. }
  63. });
  64. QAction* a2 = new QAction(QStringLiteral("查看"));
  65. menu->addAction(a2);
  66. connect(a2, &QAction::triggered, this, [&]() {
  67. QModelIndex curIndex = ui.treeView->currentIndex();
  68. if (curIndex.isValid())
  69. {
  70. auto curItem = static_cast<XPloteStandardItem*>((model->itemFromIndex(curIndex)));
  71. if (curItem != nullptr)
  72. {
  73. QString info;
  74. info.append(curItem->text());//获取当前文本.
  75. info.append(QStringLiteral("\r\n状态: %1\r\n").arg(curItem->checkState()));
  76. info.append(QStringLiteral("自己的数据(IXPloteTreeItem): %1").arg(curItem->gTreeData->toString().c_str()));
  77. PrintLog(info);
  78. }
  79. }
  80. });
  81. QAction* a5 = new QAction(QStringLiteral("展开"));
  82. menu->addAction(a5);
  83. connect(a5, &QAction::triggered, this, [&]() {
  84. QModelIndex curIndex = ui.treeView->currentIndex();
  85. if (curIndex.isValid())
  86. {
  87. ui.treeView->expand(curIndex);
  88. }
  89. });
  90. QAction* a6 = new QAction(QStringLiteral("收起"));
  91. menu->addAction(a6);
  92. connect(a6, &QAction::triggered, this, [&]() {
  93. QModelIndex curIndex = ui.treeView->currentIndex();
  94. if (curIndex.isValid())
  95. {
  96. ui.treeView->collapse(curIndex);
  97. }
  98. });
  99. QAction* a3 = new QAction(QStringLiteral("修改"));
  100. menu->addAction(a3);
  101. connect(a3, &QAction::triggered, this, [&]() {
  102. QModelIndex curIndex = ui.treeView->currentIndex();
  103. if (curIndex.isValid())
  104. {
  105. auto curItem = static_cast<XPloteStandardItem*>((model->itemFromIndex(curIndex)));
  106. if (curItem != nullptr)
  107. {
  108. QString str = QStringLiteral("天朝");
  109. curItem->gTreeData->gName = str.toStdString();
  110. curItem->setText(str);
  111. PrintLog(QStringLiteral("修改完成"));
  112. }
  113. }
  114. });
  115. QAction* a4 = new QAction(QStringLiteral("删除"));
  116. menu->addAction(a4);
  117. connect(a4, &QAction::triggered, this, [&]() {
  118. QModelIndex curIndex = ui.treeView->currentIndex();
  119. if (curIndex.isValid())
  120. {
  121. auto parentIndex = curIndex.parent();
  122. if (parentIndex.isValid())
  123. {
  124. auto parentItem = model->itemFromIndex(parentIndex);
  125. parentItem->removeRow(curIndex.row());
  126. }
  127. else
  128. {
  129. model->removeRow(curIndex.row());
  130. }
  131. }
  132. });
  133. //给菜单添加项
  134. //添加一些Tree数据.
  135. {
  136. model = new QStandardItemModel(ui.treeView); //指定父对象,便于内存管理
  137. model->setHorizontalHeaderLabels(QStringList() << QStringLiteral("名称") << QStringLiteral("说明"));
  138. ui.treeView->setModel(model);//设置数据Model,关键.
  139. rootItem1 = new XPloteStandardItem(QStringLiteral("北京"));
  140. model->appendRow(rootItem1);
  141. XPloteStandardItem* childItem1_1 = new XPloteStandardItem(QStringLiteral("故宫"));
  142. rootItem1->appendRow(childItem1_1);
  143. XPloteStandardItem* childItem1_2 = new XPloteStandardItem(QStringLiteral("子午庙"));
  144. rootItem1->appendRow(childItem1_2);
  145. rootItem1->appendRow(new XPloteStandardItem(QStringLiteral("日月潭")));
  146. rootItem1->appendRow(new XPloteStandardItem(QStringLiteral("中南海")));
  147. rootItem2 = new XPloteStandardItem(QStringLiteral("湖北"));
  148. model->appendRow(rootItem2);
  149. //model->setItem(model->indexFromItem(rootItem2).row(), 1, new XPloteStandardItem(QStringLiteral("黄鹤楼")));//设置第二列内容.
  150. XPloteStandardItem* childItem2_1 = new XPloteStandardItem(QStringLiteral("武汉"));
  151. rootItem2->appendRow(childItem2_1);
  152. //rootItem2->setChild(childItem2_1->index().row(), 1, new XPloteStandardItem(QStringLiteral("步行街")));//在第二列添加数据.
  153. XPloteStandardItem* childItem2_2 = new XPloteStandardItem(QStringLiteral("园博园")); //注意这里->rootItem2,通过父类设置其所在的行.
  154. rootItem2->appendRow(childItem2_2);
  155. //rootItem2->setChild(childItem2_2->index().row(),1,new XPloteStandardItem(QStringLiteral("揽月楼")));
  156. rootItem2->appendRow(new XPloteStandardItem(QStringLiteral("白云寺")));
  157. }
  158. }
  159. /// <summary>
  160. /// 右键菜单...
  161. /// </summary>
  162. /// <param name="pos"></param>
  163. void QtTree::on_treeView_customContextMenuRequested(const QPoint& pos)
  164. {
  165. if (ui.treeView->hasFocus()) {
  166. menu->exec(this->mapToGlobal(pos));
  167. }
  168. }

  完整的资源下载链接:

http://链接: https://pan.baidu.com/s/1HCHLJmsvV_5CRhqayFhiXg?pwd=hong 提取码: hong 复制这段内容后打开百度网盘手机App,操作更方便哦 --来自百度网盘超级会员v6的分享

 或者关注公众号 我有一座编码屋     回复 QtTree 即可获取链接

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/297456
推荐阅读
相关标签
  

闽ICP备14008679号