如何在 Godot 中创建可缩放的多行按钮?
How to create a scalable multi-line button in Godot?
Godot 中的一个 Button
只能容纳一行文本。我可以通过在按钮内放置 RichTextLabel
节点来克服这个限制。
现在按钮可以包含更多文本行,但是当需要更多行时它的高度不会自动改变。相反,文本只是溢出:
当然,我可以手动将按钮的大小调整得更高,但我希望这会根据里面的文本量自动发生。具体来说,我以编程方式生成这些按钮的列表并显示在 HBoxContainer
中,其中一些按钮的文本较长,而另一些按钮的文本较短。
有没有办法用 Godot 布局工具实现这个?
由于 Button
在 Container
中,它控制着它的 rect_size
。我们能做的最好的事情就是指定一个 rect_min_size
。没有 Control
依赖于子 Control
的布局预设。因此,回答发布的问题:不,我们无法使用 Godot 布局工具实现此目的。 我们需要一些脚本。
我们需要根据 RichTextLabel
为 Button
设置 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()
Godot 中的一个 Button
只能容纳一行文本。我可以通过在按钮内放置 RichTextLabel
节点来克服这个限制。
现在按钮可以包含更多文本行,但是当需要更多行时它的高度不会自动改变。相反,文本只是溢出:
当然,我可以手动将按钮的大小调整得更高,但我希望这会根据里面的文本量自动发生。具体来说,我以编程方式生成这些按钮的列表并显示在 HBoxContainer
中,其中一些按钮的文本较长,而另一些按钮的文本较短。
有没有办法用 Godot 布局工具实现这个?
由于 Button
在 Container
中,它控制着它的 rect_size
。我们能做的最好的事情就是指定一个 rect_min_size
。没有 Control
依赖于子 Control
的布局预设。因此,回答发布的问题:不,我们无法使用 Godot 布局工具实现此目的。 我们需要一些脚本。
我们需要根据 RichTextLabel
为 Button
设置 rect_min_size
。我们可以用 get_content_height
询问它内容的高度。这也意味着我们需要预先设置宽度。但是,当我们设置文本时它不会立即更新(我们将使用 yield
)。
显然您不希望 Container
控制 Button
的高度。如果是这样,我认为您可以从 size_flags_vertical
.
关于宽度,因为我之前解释过我们需要设置宽度来获得高度......我建议你让Container
尽可能地扩大Button
的宽度.这意味着在 size_flags_horizontal
.
然后,将 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()