如何在 Godot 中创建可缩放的多行按钮?

How to create a scalable multi-line button in Godot?

Godot 中的一个 Button 只能容纳一行文本。我可以通过在按钮内放置 RichTextLabel 节点来克服这个限制。

现在按钮可以包含更多文本行,但是当需要更多行时它的高度不会自动改变。相反,文本只是溢出:

当然,我可以手动将按钮的大小调整得更高,但我希望这会根据里面的文本量自动发生。具体来说,我以编程方式生成这些按钮的列表并显示在 HBoxContainer 中,其中一些按钮的文本较长,而另一些按钮的文本较短。

有没有办法用 Godot 布局工具实现这个?

由于 ButtonContainer 中,它控制着它的 rect_size。我们能做的最好的事情就是指定一个 rect_min_size。没有 Control 依赖于子 Control 的布局预设。因此,回答发布的问题:不,我们无法使用 Godot 布局工具实现此目的。 我们需要一些脚本。


我们需要根据 RichTextLabelButton 设置 rect_min_size。我们可以用 get_content_height 询问它内容的高度。这也意味着我们需要预先设置宽度。但是,当我们设置文本时它不会立即更新(我们将使用 yield)。


显然您不希望 Container 控制 Button 的高度。如果是这样,我认为您可以从 size_flags_vertical.

中删除所有标志

关于宽度,因为我之前解释过我们需要设置宽度来获得高度......我建议你让Container尽可能地扩大Button的宽度.这意味着在 size_flags_horizontal.

上同时设置 Fill 和 Expand 标志

然后,将 RichTextLabel 正确设置为尽可能多地占用父级 Button 的宽度,您可以读取它的高度,并使用它来设置 [=15] 的高度=] 的 Button.


还有一件事:您想将 RichTextLabel 的鼠标过滤器设置为忽略或通过,否则它将阻止按下 Button


这是我想出的代码:

var b := Button.new()
b.size_flags_vertical = 0
b.size_flags_horizontal = SIZE_EXPAND_FILL
add_child(b)

var l := RichTextLabel.new()
l.mouse_filter = Control.MOUSE_FILTER_IGNORE
l.set_anchors_and_margins_preset(Control.PRESET_WIDE)
l.text = "Some\nMultiline\nText"
b.add_child(l)

yield(get_tree(), "idle_frame")
b.rect_min_size.y = l.get_content_height()

I'd like this to happen automatically depending on the amount of text inside

遗憾的是更改文本不会调整大小,也不会更改 RichTextLabel 的最小大小。并且 RichTextLabel 没有“文本已更改”信号。也没有“bbcode 文本已更改”信号。此外,拦截这些属性可能不可行(请参阅 append_bbcode et.al)。 使用常规标签可能更容易。

无论如何,我要建议的是制作一个 Control 来包装 RichTextLabel,提供您实际需要的任何界面,以及您更改文本的任何方法,之后,您执行以下操作:

yield(get_tree(), "idle_frame")
b.rect_min_size.y = l.get_content_height()