概述

在写myList类的时候,就想到可以写一个类似的Todo清单类。

基础思路

本质还是在内部维护一个数组,在其基础上进行增删改查操作的封装为了方便存储数据,编写一个自定义内置类TodoItem,内部数组就变成了Array[TodoItem]类型的类型化数组。在这个数组基础上编写各种方法。

基于本文所写的这个类实际上已经可以写简单的清单应用了。当然为了能用于打印输出,所以我也设定了以纯字符形式输出的方法。

代码

# ========================================================

# 名称:myTodoList

# 类型:类

# 简介:专用于构造待办清单列表的类

# 作者:巽星石

# Godot版本:v4.2.2.stable.official [15073afe3]

# 创建时间:2024年4月27日13:30:09

# 最后修改时间:2024年4月27日22:17:18

# ========================================================

class_name myTodoList

var _arr:Array[TodoItem] # 数据 - 内部维护的类型化数组

# ============================= 常量与取值函数 ===========================

# 列表项状态

enum {UNCHECKED,CHECKED,CANCLE}

var state_chars := "☐☑☒" # 状态字符

# 获取对应常量的状态字符

func get_state_char(state:=UNCHECKED):

return state_chars[state]

# ============================= 内部类 ===========================

# 清单列表项

class TodoItem:

var status:int = UNCHECKED # 状态

var content:String ="" # 内容

func _init(ctn:String,state:int = UNCHECKED) -> void:

content = ctn

status = state

# ============================= 虚函数 ===========================

# 实例化

func _init(list:PackedStringArray = []) -> void:

for itm in list:

var item = TodoItem.new(itm)

_arr.append(item)

# ============================= 方法 ===========================

# -------------------- 增删改查 --------------------

# -------------------- 增

# 添加清单项

func append(itm:String,state:int = UNCHECKED) -> void:

var item = TodoItem.new(itm,state)

_arr.append(item)

# 添加多个清单项

func append_array(items:PackedStringArray,state:int = UNCHECKED) -> void:

for i in range(items.size()):

append(items[i],state)

# 在指定位置添加清单项

func insert(pos:int,itm:String,state:int = UNCHECKED) -> void:

var item = TodoItem.new(itm,state)

_arr.insert(pos,item)

# -------------------- 删

# 移除列表项

func remove(idx:int) -> void:

_arr.remove_at(idx)

# 清空列表项

func clear() -> void:

_arr.clear()

# -------------------- 改

# --------- 修改清单项的勾选状态 ---------

# 勾选列表项

func check(idx:int) -> void:

_arr[idx].status = CHECKED

# 勾选列表项

func uncheck(idx:int) -> void:

_arr[idx].status = UNCHECKED

# 勾选列表项

func cancle(idx:int) -> void:

_arr[idx].status = CANCLE

# --------- 修改清单项的值和位置 ---------

# 修改列表项的值

func set_item(idx:int,new_val:String) -> void:

_arr[idx].content = new_val

# 修改列表项的位置

func move_to(idx:int,new_pos:int) -> void:

var item = _arr[idx]

_arr.remove_at(idx)

_arr.insert(new_pos if new_pos !=0 else 0,item)

# -------------------- 查

# 获取列表项

func get_item(idx:int) ->TodoItem:

return _arr[idx]

# 返回列表项的总数

func get_count() ->int:

return _arr.size()

# -------------------- 遍历

# 遍历函数

func for_item(callback:Callable) ->void:

for i in range(_arr.size()):

callback.callv([_arr[i],i,_arr.size()])

# -------------------- 获取清单 --------------------

# 返回清单列表

func get_data() -> Array[TodoItem]:

return _arr.duplicate() # 返回副本

# 返回清单列表

func _to_string() -> String:

var strr = ""

for i in range(_arr.size()):

strr += "%s %s\n" % [get_state_char(_arr[i].status),_arr[i].content]

return strr

基础原理

class_name myTodoList

var _arr:Array[TodoItem] # 数据 - 内部维护的类型化数组

# ============================= 常量与取值函数 ===========================

# 列表项状态

enum {UNCHECKED,CHECKED,CANCLE}

var state_chars := "☐☑☒" # 状态字符

# 获取对应常量的状态字符

func get_state_char(state:=UNCHECKED):

return state_chars[state]

# ============================= 内部类 ===========================

# 清单列表项

class TodoItem:

var status:int = UNCHECKED # 状态

var content:String ="" # 内容

func _init(ctn:String,state:int = UNCHECKED) -> void:

content = ctn

status = state

观察最顶部的代码可以发现:

整个myTodoList内部维护一个名为_arr的数组,它是Array[TodoItem]的类型数组,只存储也只能存储TodoItem类型的实例TodoItem是内部类,有2个基础属性status和content,分别存储清单项的状态(是否选中或取消),以及文本内容TodoItem构造函数中默认的状态设置为UNCHECKED也就是未选中TodoItem的状态可以是UNCHECKED,CHECKED,CANCLE其中之一,分别对应未选中、选中和取消state_chars中存储了TodoItem3种状态对应的字符组成的字符串☐☑☒get_state_char()用于获取UNCHECKED,CHECKED,CANCLE对应的state_chars中的字符,用于在get_todo_list_string()中返回纯字符串的Todo清单。

基础使用

myTodoList的方法和使用基本上与myList类一致,也与GDScript的数组基本保持一致,所以上手没什么难度。除了设定状态的3个方法:

uncheck():将指定位置的项设为不勾选check():将指定位置的项设为勾选cancle():将指定位置的项设为取消

var list = myTodoList.new(["待办事项1","待办事项2","待办事项3"]) # 创建实例

list.check(0) # 选中第1项

list.cancle(1) # 取消第2项

list.append("待办事项4")

list.append("待办事项5",list.CHECKED)

list.append_array(["待办事项6","待办事项7","待办事项8"],list.CHECKED)

print(list.get_todo_list_string())

输出:

☑ 待办事项1

☒ 待办事项2

☐ 待办事项3

☐ 待办事项4

☑ 待办事项5

☑ 待办事项6

☑ 待办事项7

☑ 待办事项8

改进

使用_to_string()

_to_string()虚函数是用于在类内部自定义to_string()返回值的。在使用print()或其他打印函数时,会自动调用to_string(),打印其返回值。

我们将原来的get_todo_list_string()方法改为_to_string()。

# 返回清单列表

func _to_string() -> String:

var strr = ""

for i in range(_arr.size()):

strr += "%s %s\n" % [get_state_char(_arr[i].status),_arr[i].content]

return strr

则,在打印时,我们可以直接print()我们创建的实例:

var list = myTodoList.new(["待办事项1","待办事项2","待办事项3"]) # 创建实例

print(list)

而如果我们想要字符串本身,可以使用list.to_string()。

推荐阅读

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。