【Godot4.2】EasyTreeData通用解析

概述

之前在《【Godot4.2】Tree控件自定义树形数据ETD及其解析》一文中,实现了对带缩进的层级结构文本的解析,并将其用于Tree控件的列表项构造。

不过当时并没有实现专门的类,今天花了一点时间实现了一下。现在可以更方便的构造和解析ETD数据,并转化为其他格式。

并且EasyTreeData类,可以被理解为一个树型数据结构,可以基于它构造数据结构中的树。

本篇就介绍一下这个类的使用方法。

代码

# ========================================================
# 名称:EasyTreeData
# 类型:类
# 简介:专用于构造树形结构数据的类
# 作者:巽星石
# Godot版本:v4.2.2.stable.official [15073afe3]
# 创建时间:202442923:20:02
# 最后修改时间:202443000:57:15
# ========================================================
class_name EasyTreeData

var _root:EasyTreeItem

# ============================ 内部类 ============================
# 单项数据
class EasyTreeItem:
	var data:String
	var deep:int
	var parent:EasyTreeItem
	var children:Array[EasyTreeItem]
	
	func _init(_data:String,_deep:int) -> void:
		data = _data
		deep = _deep
		children = []
	
	# 输出ETD多行文本格式
	func _to_string() -> String:
		var sttr:= "%s%s\n" % ["\t".repeat(deep),data]
		for child in children:
			sttr += child.to_string()
		return sttr
	
	# 输出MarkDown带缩进无序列表字符串
	func to_MD_ul() -> String:
		var sttr:= "%s- %s\n" % ["\t".repeat(deep),data]
		for child in children:
			sttr += child.to_MD_ul()
		return sttr
		
	# 输出可识别的LaTex总结字符串
	func to_LaTex() -> String:
		var list_str = "\n/begin{cases}\n%s/end{cases}\n"
		var sttr:= "%s%s"
		if children.size()!=0:
			var subs = ""
			for child in children:
				subs += child.to_LaTex() + "//\n"
			sttr =  sttr % [data,list_str % subs]
		else:
			sttr =  sttr % [data,""]
		return sttr.replace("/","\\")


# ============================ 虚函数 ============================
# 转化为字符串
func _to_string() -> String:
	return "" if !_root else _root.to_string()

# 返回ETD多行文本
func get_data() -> String:
	return _to_string()

# 输出MarkDown带缩进无序列表字符串
func to_MD_ul() -> String:
	return "" if !_root else _root.to_MD_ul()

func to_LaTex() -> String:
	return "" if !_root else _root.to_LaTex()
# ============================ 方法 ============================
# 创建并返回一个EasyTreeItem实例
func create_item(text:String,p_node:EasyTreeItem = null) -> EasyTreeItem:
	var itm = EasyTreeItem.new(text,0)
	if _root:
		if p_node:
			itm.deep = p_node.deep + 1
			itm.parent = p_node
			p_node.children.append(itm)
		else:
			itm.deep = _root.deep + 1
			itm.parent = _root
			_root.children.append(itm)
	else:
		_root = itm
	return itm

# 由多行文本创建
static func new_with_etd_str(etd_str:String) ->EasyTreeData:
	var edt = EasyTreeData.new()

	var items = etd_str.split("\n",false)    # 将ETD字符串按行切分为字符串数组
	var pre_itm:EasyTreeItem                 # 记录前一项
	var p_itm:EasyTreeItem = null            # 记录父节点

	# 遍历每行数据
	for i in range(items.size()):
		# 第1行直接添加为Tree控件的根节点(跳过下面if部分)
		# 从第2行开始比较当前行与前一行的缩进深度(也就是\t的数目)
		if i > 0: 
			var d_deep = deep(items[i-1]) - deep(items[i])  # 与前一行数据的缩进差值
			match d_deep:
				-1:                                # 缩进比前一项深:
					p_itm = pre_itm                # 将前一项作为父节点
				0:                                 # 缩进深度与前一项一样:
					p_itm = pre_itm.parent   # 父节点与前一项父节点一样
				_:                                 
					if d_deep>0:                   # 缩进比前一项浅
												   # 通过缩进差值计算获得合适的父节点
						p_itm = pre_itm            
						for j in range(d_deep+1):
							p_itm = p_itm.parent
		
		# 实际创建和添加TreeItemTree控件
		var itm:EasyTreeItem = edt.create_item(items[i].replace("\t",""),p_itm)
		pre_itm = itm                              # 将当前项记录为前一项
	return edt

# 返回字符串的Tab缩进值
static func deep(sttr:String):
	return sttr.rstrip(" ").count("\t")

使用方法

基础使用

EasyTreeData在使用和API名称上模仿了Godot的Tree控件和TreeItem类。所以熟悉Tree控件和TreeItem的Godoter可以直接零难度上手。

var edt = EasyTreeData.new()             # 创建实例
# 创建根节点
var root = edt.create_item("根节点")  
var itm = edt.create_item("节点1",root)  # 创建根节点的子节点
print(edt)   # 打印输出相应的EDT字符串

输出:

根节点
	节点1

用ETD多行文本数据创建

你可以用多行文本形式构造一个ETD数据字符串,也就是一个带层级关系和缩进关系的多行文本:

var etd = """
条目1
	条目1.1
	条目1.2
		条目1.2.1
		条目1.2.2
	条目1.3
"""

通过调用new_with_etd_str()静态方法,并传入上面的ETD数据字符串,可以构造一个新的EasyTreeData实例。

var edt = EasyTreeData.new_with_etd_str(etd)
print(edt)

输出:

条目1
	条目1.1
	条目1.2
		条目1.2.1
		条目1.2.2
	条目1.3

可以看到与传入的ETD数据字符串一致,但是你可以在此基础上继续添加新的数据项。

获取MarkDown的无序列表字符串

print(edt.to_MD_ul())  

输出:

- 条目1
	- 条目1.1
	- 条目1.2
		- 条目1.2.1
		- 条目1.2.2
	- 条目1.3

这段代码可以直接粘贴到MarkDown编辑器中,变为带层级的无序列表样式,效果如下:


  • 条目1
    • 条目1.1
    • 条目1.2
      • 条目1.2.1
      • 条目1.2.2
    • 条目1.3

将ETD解析为LaTex总结笔记

print(edt.to_LaTex())

输出:

条目1
\begin{cases}
条目1.1\\
条目1.2
\begin{cases}
条目1.2.1\\
条目1.2.2\\
\end{cases}
\\
条目1.3\\
\end{cases}

粘贴到MarkDown编辑器的LaTex公式中,显示为:
条 目 1 { 条 目 1.1 条 目 1.2 { 条 目 1.2.1 条 目 1.2.2 条 目 1.3 条目1 \begin{cases} 条目1.1\\ 条目1.2 \begin{cases} 条目1.2.1\\ 条目1.2.2\\ \end{cases} \\ 条目1.3\\ \end{cases} 11.11.2{1.2.11.2.21.3
基于此,我们可以很方便的通过简单的层级缩进文本,或者Markdown中带层级缩进的无序列表,实现比较复杂的Latex公式总结笔记的转化。

比如,我们构造如下的ETD字符串:

数据结构
	线性结构
		栈
		队列
		双端列表
		列表
	非线性结构
		图
		树

生成的总结笔记:
数 据 结 构 { 线 性 结 构 { 栈 队 列 双 端 列 表 列 表 非 线 性 结 构 { 图 树 数据结构 \begin{cases} 线性结构 \begin{cases} 栈\\ 队列\\ 双端列表\\ 列表\\ \end{cases} \\ 非线性结构 \begin{cases} 图\\ 树\\ \end{cases} \\ \end{cases} 线线{

展望

紧缩字串(暂未实现)

可以将ETD多行文本形式转化为如下的括号嵌套结构的单行字符串。这样更容易压缩存储。

此外,也可以编写相应函数来解析为树形结构数据。

条目1[条目1.1,条目1.2[条目1.2.1,条目1.2.2]条目1.3]

获取字典与JSON形式

在上面基础上,我们可以获取对应的字典以及JSON字符串。

用于树控件

  • 通过提供静态方法,可以用于任意Tree控件的数据项构造。

用于构造菜单

  • 菜单是多个树结构

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

分布式与一致性协议之Raft算法(二)

Raft算法 什么是任期 我们知道,议会选举中的领导者是有任期的,当领导者任命到期后,需要重新再次选举。Raft算法中的领导者也是有任期,每个任期由单调递增的数字(任期编号)标识。比如,节点A的任期编号是1。任期编号会…

Spark-机器学习(8)分类学习之随机森林

在之前的文章中,我们学习了分类学习之支持向量机决策树支持向量机,并带来简单案例,学习用法。想了解的朋友可以查看这篇文章。同时,希望我的文章能帮助到你,如果觉得我的文章写的不错,请留下你宝贵的点赞&a…

【全开源】Java上门老人护理老人上门服务类型系统小程序APP源码

功能: 服务分类与选择:系统提供详细的老人护理服务分类,包括日常照护、康复训练、医疗护理等,用户可以根据老人的需求选择合适的服务项目。预约与订单管理:用户可以通过系统预约护理服务,并查看订单详情&a…

mybatis工程需要的pom.xml,以及@Data 、@BeforeEach、@AfterEach 的使用,简化mybatis

对 “mybatis - XxxMapper.java接口中方法的参数 和 返回值类型&#xff0c;怎样在 XxxMapper.xml 中配置的问题” 这篇文章做一下优化 这个pom.xml文件&#xff0c;就是上面说的这篇文章的父工程的pom.xml&#xff0c;即&#xff1a;下面这个pom.xml 是可以拿来就用的 <?…

Python爬虫(入门版)

1、爬虫是什么 简单的来说&#xff1a;就是用程序获取网络上数据。 2、爬虫的原理 如果要获取网络上数据&#xff0c;我们要给爬虫一个网址&#xff08;程序中通常叫URL&#xff09;&#xff0c;爬虫发送一个HTTP请求给目标网页的服务器&#xff0c;服务器返回数据给客户端&am…

帕累托森林李朝政博士受聘「天工开物开源基金会」专家顾问

导语&#xff1a; 开源铸造了当前最前沿的科技引擎。开源驱动了软件生态&#xff0c;也以指数级速度驱动硬件生态。 3月中旬&#xff0c;天工开物开源基金会授予李朝政博士专家顾问&#xff0c;表彰他积极推动参与中国智能软件生态的建设&#xff0c;期待一起共筑未来新生态。…

稳扎稳打 部署丝滑 开源即时通讯(IM)项目OpenIM源码部署流程(linux windows mac)

背景 OpenIM包含多个关键组件&#xff0c;每个都是系统功能必不可少的一部分。具体来说&#xff0c;MongoDB 用于持久化存储&#xff1b;Redis 用作缓存&#xff1b;Kafka 用于消息队列&#xff1b;Zookeeper 用于服务发现&#xff1b;Minio 用于对象存储。这些组件的众多可能会…

C# Web控件与数据感应之 ListControl 类

目录 关于数据感应 ListControl 类类型控件 范例运行环境 数据感应通用方法 设计 实现 调用示例 数据源 调用 小结 关于数据感应 数据感应也即数据捆绑&#xff0c;是一种动态的&#xff0c;Web控件与数据源之间的交互&#xff0c;诸如 System.Web.UI.WebControls 里…

RustGUI学习(iced)之小部件(四):如何使用单选框radio部件?

前言 本专栏是学习Rust的GUI库iced的合集&#xff0c;将介绍iced涉及的各个小部件分别介绍&#xff0c;最后会汇总为一个总的程序。 iced是RustGUI中比较强大的一个&#xff0c;目前处于发展中&#xff08;即版本可能会改变&#xff09;&#xff0c;本专栏基于版本0.12.1. 概述…

颠倒二进制位

优质博文IT-BLOG-CN 一、题目 颠倒给定的32位无符号整数的二进制位。 请注意&#xff0c;在某些语言&#xff08;如 Java&#xff09;中&#xff0c;没有无符号整数类型。在这种情况下&#xff0c;输入和输出都将被指定为有符号整数类型&#xff0c;并且不应影响您的实现&…

NI CRIO 9045 LABVIEW2020

1.labview工程如果要访问CRIO&#xff0c;需要设置以下&#xff0c;否则在项目中连接失败。 2.项目中如果要传文件&#xff0c;需要安装WebDEV 3.使用WebDAV将文件传输到实时(RT)目标 https://knowledge.ni.com/KnowledgeArticleDetails?idkA03q000000YGytCAG&lzh-CN

[python数据处理系列] 深入理解与实践基于聚类的过采样与欠采样技术:以K-Means为例

目录 一、过采样介绍 (一)什么是过采样 (二)过采样的优点 (三)过采样的缺点 二、欠采样介绍 (一)什么是欠采样 (二)欠采样的优点 (三)欠采样的缺点 三、基于聚类的欠抽样方法(K-Means欠采样/KMeans-Undersampling) (一)KMeans欠采样原理及其步骤介绍 (二)为什么不采…

UE4 Widget制作搜索框

效果&#xff1a; 一、控件层级结构 1.父控件层级结构 2.子控件层级结构 二、蓝图 1.先清除掉创建子项&#xff08;注意&#xff1a;这里使用的是reverse循环&#xff01;&#xff09; 2.判断是否含有关键字&#xff0c;创建子控件

盲人手机导航:科技之光引领无障碍出行新纪元

在这个日新月异的数字时代&#xff0c;科技不仅改变了我们获取信息的方式&#xff0c;更在无声中拓宽了视障人士的生活半径。盲人手机导航这一创新技术&#xff0c;正逐步成为他们探索世界、实现独立出行的重要伙伴。 对于大多数人而言&#xff0c;日常出行或许只是一次…

Vue3+Nuxt3 从0到1搭建官网项目(SEO搜索、中英文切换、图片懒加载)

Vue2Nuxt2 从 0 到1 搭建官网~ 想开发一个官网&#xff0c;并且支持SEO搜索&#xff0c;当然离不开我们的 Nuxt &#xff0c;Nuxt2 我们刚刚可以熟练运用&#xff0c;现在有出现了Nuxt3&#xff0c;那通过本篇文章让我们一起了解一下。 安装 Nuxt3 // npx nuxilatest init &…

解析Redis Key Prefix配置之谜:双冒号“::”的由来与作用

前言 在使用Spring Boot集成Redis进行应用开发时&#xff0c;为了增强缓存键的可读性和管理性&#xff0c;我们常常会在配置文件中设定一个全局的key-prefix。如果你发现存储至Redis的键自动附加了“::”&#xff0c;本文将深入探讨这一现象背后的原因&#xff0c;解析Spring …

Redis线程模型及性能优化概述

redis线程模型&#xff1a; 网络模块命令处理 redis的性能&#xff1a; 一个取决于物理内存&#xff0c;另一个是对于socket请求的处理速度。 4.0以前 单线程模式 请求流程&#xff1a;对于一个请求&#xff0c;线程会根据操作产生相应的事件&#xff08;读&#xff0c;写事…

张大哥笔记:服务器有挖矿木马程序,该如何处理?

这篇文章发表于2021年&#xff0c;今天借这个平台再发布一下&#xff0c;希望对大家有所帮助&#xff01; 今天收到一个粉丝求助&#xff0c;说收到了阿里云官方短信通知提示有挖矿程序&#xff0c;要求立即整改&#xff0c;否则会关停服务器&#xff0c;以下是我和他的对话内…

机器学习:深入解析SVM的核心概念(问题与解答篇)【二、对偶问题】

对偶问题 **问题一&#xff1a;什么叫做凸二次优化问题&#xff1f;而且为什么符合凸二次优化问题&#xff1f;**为什么约束条件也是凸的半空间&#xff08;Half-Space&#xff09;凸集&#xff08;Convex Set&#xff09;半空间是凸集的例子SVM 约束定义的半空间总结 **问题二…

CTFHub-Web-SSRF

CTFHub-Web-SSRF-WP 一、内网访问 1.题目提示说访问127.0.0.1的flag.php&#xff0c;在URL后面添加路径没想到直接访问成功 二、伪协议读取文件 1.题目提示说访问Web目录下的flag.php&#xff0c;联想到Web目录一般存放于/var/www/html/里&#xff0c;去修改URL尝试进行访问…