【NX】NXOpen::BlockStyler::Tree的个人使用类分享

news2024/11/26 12:23:10

网上关于NXOpen::BlockStyler::Tree的例子不是太多,控件默认id名称为tree_control01,因为例子不多很多功能得自己写,虽然NXOpen::BlockStyler::Tree的封装已经不错了,但是实际使用起来也不是很方便,比如像获取所有节点,指定节点的子节点等功能,都没有直接实现,而如果想实现层级关系,则更是没得,需要自己整理而且经过繁琐验证,这些工作我已经做过了,并且经过了时间的考验,于是特此分享出来,注意每个函数的功能我都已经写好注释了。

首先是声明:

//author:autumoon
//联系:9506@163.com
//日期:2023-07-05 
class CNXTreeCtrlUser
{
public:
	CNXTreeCtrlUser();
	~CNXTreeCtrlUser(void);

public:
	//在某个节点下最后添加一个节点并且自动展开
	bool AddExpandNode(BlockStyler::Node* pNewNode, BlockStyler::Node* pParentNode);

	//在某个节点的同级别最后处添加一个节点并且自动展开
	bool AddTheSameLevelExpandNode(BlockStyler::Node* pNewNode, BlockStyler::Node* pTheSameLevelNode);

	//树是否可用
	void EnableTreeCtrl(bool bEnabled = true);

	//设置树列表高度
	void SetTreeHeight(int nHeight = 300);

	//设置控件指针
	void SetTreePtr(BlockStyler::Tree * tree){m_pTreeCtrl = tree;}

public:
	//判断某个节点是不是对应的级别
	static bool IsLevelNode(BlockStyler::Tree* tree, BlockStyler::Node* inputNode, int nLevel);

	//清空某个节点的子节点
	static void ClearChildNodes(BlockStyler::Tree* tree, BlockStyler::Node* inputNode);

	//清空某个级别以及以上的子节点 nLevel = 0时清空所有 等于1时保留根节点 等于2时保留根节点以及第二级 以此类推
	static void ClearTreeLevelNodes(BlockStyler::Tree* tree, int nLevel = 1);

	//获取某个级别的节点 nLevel = 0时所有 等于1时获得第一级 以此类推 bIncludeChild控制是否包该级别的子节点
	static void GetTreeLevelNodes(BlockStyler::Tree* tree, std::vector<BlockStyler::Node*> &nodes, int nLevel = 1, bool bIncludeChild = false);

	//遍历某个节点的子节点,之所以写成这种形式,是为了方便添加多个节点  bIncludeChild控制是否包含子节点
	static void GetChildNodes(BlockStyler::Node* inputNode, std::vector<BlockStyler::Node*> &nodes, bool bIncludeChild = true);

	//得到树控件所有节点 bIncludeChild控制是否包含子节点
	static std::vector<BlockStyler::Node*> GetAllNodes(BlockStyler::Tree* tree, bool bIncludeChild = true);

	//清空树节点
	static void ClearTree(BlockStyler::Tree* tree);

protected:
	BlockStyler::Tree * m_pTreeCtrl;
};

接着是实现:

//author:autumoon
//联系:9506@163.com
//日期:2023-07-05 
using namespace NXOpen::BlockStyler;


CNXTreeCtrlUser::CNXTreeCtrlUser(void):m_pTreeCtrl(nullptr)
{
}


CNXTreeCtrlUser::~CNXTreeCtrlUser(void)
{
}

bool CNXTreeCtrlUser::AddExpandNode(BlockStyler::Node* pNewNode, BlockStyler::Node* pParentNode)
{
	if (pNewNode == nullptr || pParentNode == nullptr)
	{
		return false;
	}

	m_pTreeCtrl->InsertNode(pNewNode, pParentNode, nullptr, Tree::NodeInsertOptionLast);//子节点
	pNewNode->Expand(Node::ExpandOptionExpand);

	return true;
}

bool CNXTreeCtrlUser::AddTheSameLevelExpandNode(BlockStyler::Node* pNewNode, BlockStyler::Node* pTheSameLevelNode)
{
	if (pNewNode == nullptr || pTheSameLevelNode == nullptr)
	{
		return false;
	}

	m_pTreeCtrl->InsertNode(pNewNode, pTheSameLevelNode->ParentNode(), nullptr, Tree::NodeInsertOptionLast);//子节点

	pNewNode->Expand(Node::ExpandOptionExpand);

	return true;
}

void CNXTreeCtrlUser::EnableTreeCtrl(bool bEnabled /*= true*/)
{
	if (m_pTreeCtrl)
	{
		m_pTreeCtrl->GetProperties()->SetLogical("Enable", bEnabled);
	}
}

void CNXTreeCtrlUser::SetTreeHeight(int nHeight /*= 300*/)
{
	if (m_pTreeCtrl)
	{
		this->m_pTreeCtrl->GetProperties()->SetInteger("Height",300);//设置树列表高度
	}
}

bool CNXTreeCtrlUser::IsLevelNode(BlockStyler::Tree* tree, BlockStyler::Node* inputNode, int nLevel)
{
	std::vector<Node*> vNodes;

	GetTreeLevelNodes(tree, vNodes, nLevel, false);

	size_t nNodeCount = vNodes.size();

	for (size_t i = 0; i < nNodeCount; ++i)
	{
		if (vNodes[i] == inputNode)
		{
			return true;
		}
	}

	return false;
}

void CNXTreeCtrlUser::ClearChildNodes(BlockStyler::Tree* tree, BlockStyler::Node* inputNode)
{
	if (tree && inputNode)
	{
		std::vector<BlockStyler::Node*> nodes;
		GetChildNodes(inputNode, nodes, false);
		for (size_t i = 0; i < nodes.size(); i++)
		{
			tree->DeleteNode(nodes[i]);
		}
	}
}

void CNXTreeCtrlUser::ClearTreeLevelNodes(BlockStyler::Tree* tree, int nLevel /*= 1*/)
{
	if (tree && nLevel >= 0)
	{
		Node* pRootNode = tree->RootNode();

		//每个层级的node由对应的层级的vector存储
		std::vector<Node*> vNodes;

		GetTreeLevelNodes(tree, vNodes, nLevel);

		for (size_t i = 0; i < vNodes.size(); i++)
		{
			tree->DeleteNode(vNodes[i]);
		}
	}
}

void CNXTreeCtrlUser::GetTreeLevelNodes(BlockStyler::Tree* tree, std::vector<BlockStyler::Node*> &nodes, int nLevel /*= 1*/, bool bIncludeChild /*= false*/)
{
	if (tree && nLevel >= 0)
	{
		Node* pRootNode = tree->RootNode();

		//每个层级的node由对应的层级的vector存储
		std::vector<std::vector<Node*>> vvNodes(nLevel + 1);

		//可能有多个根节点
		while (pRootNode)
		{
			vvNodes[0].push_back(pRootNode);
			pRootNode = pRootNode->NextSiblingNode();
		}

		//满足条件则继续,但不允许循环超过1000次,避免死循环
		int nLoopCount = 0, nMaxLoop = 1000;

		int nCurLevel = nLevel;

		while(nCurLevel-- > 0)
		{
			if (++nLoopCount > nMaxLoop)
			{
				break;
			}

			int nLastLevelIndex = nLevel - nCurLevel - 1;
			std::vector<Node*>& vCurLevelRoots = vvNodes[nLastLevelIndex];
			int nCurLevelIndex = nLastLevelIndex + 1;
			for (size_t i = 0; i < vCurLevelRoots.size(); ++i)
			{
				GetChildNodes(vCurLevelRoots[i], vvNodes[nCurLevelIndex], false);
			}
		}

		nodes.insert(nodes.end(), vvNodes[nLevel].begin(), vvNodes[nLevel].end());
	}
}

void CNXTreeCtrlUser::GetChildNodes(BlockStyler::Node* inputNode, std::vector<BlockStyler::Node*> &nodes, bool bIncludeChild /*= true*/)
{
	if (inputNode)
	{
		Node* node = inputNode->FirstChildNode();

		while (node != nullptr)
		{
			nodes.push_back(node);
			
			if (bIncludeChild)
			{
				GetChildNodes(node, nodes);
			}

			node = node->NextSiblingNode();
		}
	}
}

std::vector<NXOpen::BlockStyler::Node*> CNXTreeCtrlUser::GetAllNodes(BlockStyler::Tree* tree, bool bIncludeChild /*= true*/)
{
	Node *nd = tree->RootNode();

	std::vector<Node*> res;
	while (nd != nullptr)
	{
		res.push_back(nd);
		if (bIncludeChild)
		{
			GetChildNodes(nd, res);
		}
		nd = nd->NextSiblingNode();
	}

	return res;
}

void CNXTreeCtrlUser::ClearTree(Tree* tree)
{
	if (tree)
	{
		std::vector<BlockStyler::Node*> vNodes = GetAllNodes(tree, false);
		for (size_t i = 0; i < vNodes.size(); i++)
		{
			tree->DeleteNode(vNodes[i]);
		}
	}
}

如果在使用中遇到什么问题,欢迎交流与讨论。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/722494.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于PyQt5的桌面图像调试仿真平台开发(8)锐化

系列文章目录 基于PyQt5的桌面图像调试仿真平台开发(1)环境搭建 基于PyQt5的桌面图像调试仿真平台开发(2)UI设计和控件绑定 基于PyQt5的桌面图像调试仿真平台开发(3)黑电平处理 基于PyQt5的桌面图像调试仿真平台开发(4)白平衡处理 基于PyQt5的桌面图像调试仿真平台开发(5)…

机器学习基础之《特征工程(2)—特征工程介绍》

一、什么是特征工程 机器学习领域的大神Andrew Ng(吴恩达)老师说“Coming up with features is difficult, time-consuming, requires expert knowledge. “Applied machine learning” is basically feature engineering. ” 注&#xff1a;业界广泛流传&#xff1a;数据和特…

论文阅读-DF-Platter: Multi-Face Heterogeneous Deepfake Dataset(多人脸异构深度伪造数据集)

一、论文信息 文章名称&#xff1a;DF-Platter: Multi-Face Heterogeneous Deepfake Dataset 作者团队&#xff1a; 会议&#xff1a;cvpr2023 数据集地址&#xff1a;http://iab-rubric.org/df-platter-database 二、动机与创新 动机 目前大多数研究工作都集中在个人外表…

【零基础入门学习Python---Python中安全编程和测试之快速入门实践】

&#x1f680; 零基础入门学习Python&#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜…

Mysql基础之SQL语句

作定期复习和查询用&#xff0c;打开这篇博客提高效率&#xff0c;避免回视频或者百度上找 &#x1f442; 无论你多怪异我还是会喜欢你&#xff08;《刺客伍六七》动画推广版片尾曲&#xff09; - 周子琰 - 单曲 - 网易云音乐 内容来自B站黑马Mysql&#xff0c;检索使用 附上…

浅析Lambda架构

大家好&#xff0c;今天我们来介绍一个用于亿级实时数据分析架构Lambda架构。 Lambda架构 Lambda架构&#xff08;Lambda Architecture&#xff09;是由Twitter工程师南森马茨&#xff08;Nathan Marz&#xff09;提出的大数据处理架构。这一架构的提出基于马茨在BackType和Tw…

Python GUI编程利器:Tkinker中的消息和文本(7)

小朋友们好&#xff0c;大朋友们好&#xff01; 我是猫妹&#xff0c;一名爱上Python编程的小学生。 和猫妹学Python&#xff0c;一起趣味学编程。 今日目标 实现下面效果&#xff1a; 消息(Message类) 消息用于显示多行文本消息&#xff0c;对标签进行替代&#xff0c;如果…

【数学建模】国赛真题分析 2012 A题 葡萄酒的评价

2012 A题 葡萄酒的评价 优秀论文地址&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/19WGpybgM6RncxTYhx61JRA?pwdvl22 提取码&#xff1a;vl22 –来自百度网盘超级会员V6的分享 确定葡萄酒质量时一般是通过聘请一批有资质的评酒员进行品评。每个评酒员在对葡萄酒进…

GWIN入门-完整一个程序

GWIN入门-完整一个程序 新建工程 右击工程名,添加.v文件 编写功能文件 /* timescale是Verilog HDL 中的一种时间尺度预编译指令,它用来定义模块的仿真时的时间单位和时间精度。 */`timescale 1ns/1ps module LED(input wire clk

第三步:STM32F4时钟介绍

1.0 时钟系统框图 1.1 时钟系统知识 1. STM32 有5个时钟源:HSI、HSE、LSI、LSE、PLL。 ①、HSI是高速内部时钟&#xff0c;RC振荡器&#xff0c;频率为16MHz&#xff0c;精度不高。可以直接作为系统 时钟或者用作PLL时钟输入。    ②、HSE是高速外部时钟&#xff0c;可接石英…

机器学习PCA + LogisticRegression 训练和预测 输出混淆矩阵

from sklearn.decomposition import PCA# --------------------------------------------- # 最佳主成分数量 pca = PCA(n_components=None) pca.fit_transform(x_train) var_values = pca.explained_variance_ratio_def select_best_components(var_, goal_var):best_componen…

flutter3.7版本下使用flutter boost解决使用platview崩溃或异常问题

背景 工程使用了混合开发&#xff0c;使用flutter boost插件&#xff0c;flutter 的activity1 frament1 跳转activity2 frament2&#xff0c;frament1 包含platformView&#xff0c;按照上面老哥解决崩溃问题的基础上&#xff0c;出现activity2 frament2返回activity1 framen…

百度--搜索引擎是怎么实现的--如何制作一个搜索浏览器

1.搜索引擎是怎么实现的&#xff1f; 搜索引擎是通过以下步骤实现的&#xff1a; 网页抓取&#xff08;Crawling&#xff09;&#xff1a;搜索引擎会使用网络爬虫&#xff08;Web Crawler&#xff09;自动地从互联网上抓取网页内容。爬虫按照一定的规则遍历网页并提取网页内容…

数组之前缀和

1.前缀和 前缀和的概念:前缀和是指数组中从开始位置到当前位置的所有位置的元素之和,它可以通过累加数组元素来计算,一般来说,我们可以使用前缀和数组在常数时间复杂度内计算任意区间的和. 注意:特别是需要频繁的计算区间和的情况,可以通过先预先计算前缀和数组,可以将时间复…

经典神经网络(7)DenseNet及其在Fashion-MNIST数据集上的应用

经典神经网络(7)DenseNet及其在Fashion-MNIST数据集上的应用 1 DenseNet的简述 DenseNet不是通过更深或者更宽的结构&#xff0c;而是通过特征重用来提升网络的学习能力。 ResNet 的思想是&#xff1a;创建从“靠近输入的层” 到 “靠近输出的层” 的直连。而DenseNet 做得更…

idea取消右侧边缘提示信息;IDEA使用心得:工作区右边框提示信息

idea的提示是很人性的&#xff0c;合理使用一定程度上也会提升个人的编码水平 最终效果&#xff1a;能看到weak warning个数&#xff0c;但侧边栏不会显示直接清爽 但是idea在检查代码时有一种警告叫做weak warning 什么是weak warning 图中这种只是其中一种&#xff0c;这种…

导出本地文件(模板)

/*** 导出模板*/GetMapping("export/template")ApiOperationSupport(order 16)ApiOperation(value "导出模板")public void exportTemplate(HttpServletResponse response) {List<JointExcel> list new ArrayList<>();ClassPathResource cl…

Fortran 中的 goto 语句

注意项 避免滥用&#xff1a;Fortran 90引入了结构化编程的概念&#xff0c;切记不要滥用goto语句明确标签&#xff1a;在使用goto语句时&#xff0c;标签要明确避免跳转过多&#xff1a;过多的跳转会增加代码的复杂性和可读性避免跳转到循环内部&#xff1a;在循环内部使用go…

力扣 93. 复原 IP 地址

题目来源&#xff1a;https://leetcode.cn/problems/restore-ip-addresses/description/ C题解&#xff1a;递归回溯法。 递归参数&#xff1a;因为不能重复分割&#xff0c;需要ind记录下一层递归分割的起始位置&#xff1b;还需要一个变量num&#xff0c;记录ip段的数量。递…

【设计模式】第二十章:解释器模式详解及应用案例

系列文章 【设计模式】七大设计原则 【设计模式】第一章&#xff1a;单例模式 【设计模式】第二章&#xff1a;工厂模式 【设计模式】第三章&#xff1a;建造者模式 【设计模式】第四章&#xff1a;原型模式 【设计模式】第五章&#xff1a;适配器模式 【设计模式】第六章&…