如何使用基础 node/class 枚举?

How to use base node/class enums?

也许这是一个非常愚蠢的问题,但我在 Google 上找不到答案。

Godot中有一个节点——TextEdit。它有几个枚举。其中之一称为 MenuItems。其中之一是 MENU_CLEAR 和灰色的“= 3”。它的描述是:“擦除整个 TextEdit 文本。”

我的问题是:如何使用此信息清除整个 TextEdit 文本?

我试着用

访问它
$TextEdit.MENU_CLEAR -> nothing

我试着走得更远

$TextEdit.MenuItems.MENU_CLEAR -> nothing

我试着把它作为一个函数调用

$TextEdit.MENU_CLEAR() -> nothing

但是,如果我尝试打印它,我会得到它的编号

print($TextEdit.MENU_CLEAR) -> "3"

MENU_CLEAR 的描述,至少对我来说,暗示那里某处有一个函数,一旦我调用 MENU_CLEAR 就应该执行该函数。但是我做错了什么。请帮助

编辑1: 这是我的一段代码(只是检查什么有效,运行 IF 之后的所有内容一次一行):

if $TextEdit.get_line_count() > 6:
    $TextEdit.text = ""
    $TextEdit.menu_option($TextEdit.MENU_CLEAR)

这是我想要做的:

if $TextEdit.get_line_count() > 6:
    $TextEdit.select(1, 0, 1, 0)    #selects the oldest line
    $TextEdit.menu_option($TextEdit.MENU_CUT)    #deletes it

这是我现在得到的截图 See the slider on the right side 这就是我想要的 Just 6 lines 所以屏幕上应该总是一次只有 6 行,旧的行应该被删除。这就是我遇到枚举问题的地方,这就是 post 的原因。 P.S。 只读 设置为 false


正在清除 TextEdit

我会使用 $TextEdit.text = "" 清除所有文本。


解决您的问题。 MENU_CLEAR 是一个常数。它的值为 3。它本身不做 3 做不到的事情。

然而,enum(这是带有名称的常量列表)被定义是因为某些东西使用它们。要找出什么,我建议您在文档中搜索 enum(在本例中为 MenuItems)的名称(特别是在相同的 class 上)。

在这种情况下,我们找到了 menu_option 方法。来自文档:

void menu_option ( int option )

Triggers a right-click menu action by the specified index. See MenuItems for a list of available indexes.

因此,您可以像这样使用它:

$TextEdit.menu_option(TextEdit.MENU_CLEAR)

是的,这也有效:

$TextEdit.menu_option($TextEdit.MENU_CLEAR)

或者你可以这样做(这是一样的,只是不太清楚它的意思):

$TextEdit.menu_option(3)

从 TextEdit 的开头删除行

假设我们要删除开头的行。我们将删除的行数将是 lines_to_remove(例如 1)。

我们可以使用 menu_option 来做到这一点。像这样:

  1. Select 我们要删除的行。换句话说,select 从第一行的开始 (0) 到第一行的开始 (lines_to_remove):

    $TextEdit.select(0, 0, lines_to_remove, 0)
    
  2. 清除 剪切:

    $TextEdit.menu_option(TextEdit.MENU_CUT)
    

    这将删除 selected 文本。但是,它也会设置剪贴板。

或者,我们可以操纵 text。例如:

var lines:Array = $TextEdit.text.split("\n")
var new_text := ""
for index in lines.size() - lines_to_remove:
    if index > 0:
        new_text += "\n"

    new_text += str(lines[index + lines_to_remove])

$TextEdit.text = new_text

这里我得到文本 $TextEdit.text 并用新行将其拆分,这给了我一个 Array。然后我将我想要保留的 Array 中的元素连接起来(即跳过我想要删除的元素),并将结果设置回 $TextEdit.text.


无论采用哪种方法,您都会发现光标将位于文本的开头。

因此,我们将在操作文本之前存储位置:

var cursor_line:int = $TextEdit.cursor_get_line()
var cursor_column:int = $TextEdit.cursor_get_column()

然后再设置回去...嗯,其实我们要减去我们删除的行数,然后再设置回去:

cursor_line -= lines_to_remove
$TextEdit.cursor_set_line(cursor_line)
$TextEdit.cursor_set_column(cursor_column)

如果结果为负 cursor_line,它将被放在第一行。我想在那种情况下我可以检查并将 cursor_linecursor_column 都设置为零,但是在尝试这个时这不是问题。


限制TextEdit的行数

现在,如果您想确保最多有给定的行数(例如六行)。我们可以读取我们有多少行,减去你允许的最大值,如果结果为正,那就是要删除多少行:

var target_number_of_lines := 6
var lines_to_remove:int = $TextEdit.get_line_count() - target_number_of_lines
if lines_to_remove > 0:
    pass # rest of the code here

为什么您需要这样做而不只是删除第一行?因为用户可能一次粘贴多行。说到这里,这是为了 "text_changed" 信号上的 运行(尽管它也适用于 _process):

func _on_TextEdit_text_changed() -> void:
    var target_number_of_lines := 6
    var lines_to_remove:int = $TextEdit.get_line_count() - target_number_of_lines
    if lines_to_remove > 0:
        var cursor_line:int = $TextEdit.cursor_get_line()
        var cursor_column:int = $TextEdit.cursor_get_column()

        $TextEdit.select(0, 0, lines_to_remove, 0)
        $TextEdit.menu_option(TextEdit.MENU_CUT)

        cursor_line -= lines_to_remove
        $TextEdit.cursor_set_line(cursor_line)
        $TextEdit.cursor_set_column(cursor_column)

由于此版本正在剪切文本,因此会写入剪贴板。


操纵 text 属性 也有效(并且不写入剪贴板)。这是代码:

func _on_TextEdit_text_changed() -> void:
    var target_number_of_lines := 6
    var lines_to_remove:int = $TextEdit.get_line_count() - target_number_of_lines
    if lines_to_remove > 0:
        var cursor_line:int = $TextEdit.cursor_get_line()
        var cursor_column:int = $TextEdit.cursor_get_column()

        var lines:Array = $TextEdit.text.split("\n")
        var new_text := ""
        for index in lines.size() - lines_to_remove:
            if index > 0:
                new_text += "\n"

            new_text += str(lines[index + lines_to_remove])

        $TextEdit.text = new_text

        cursor_line -= lines_to_remove
        $TextEdit.cursor_set_line(cursor_line)
        $TextEdit.cursor_set_column(cursor_column)