如何在 Godot 中创建可扩展的多行按钮?
Godot 中的 Button
只能容纳一行文本。我可以通过将 RichTextLabel
节点放置在按钮内来克服此限制。
现在按钮可以包含更多行文本,但当需要更多行时,其高度不会自动更改。相反,文本只是溢出:
当然,我可以手动将按钮的大小调整得更大,但我希望根据内部文本的数量自动发生这种情况。具体来说,我以编程方式生成这些按钮的列表,并在 HBoxContainer
内显示,其中一些按钮具有较长的文本,而另一些按钮则具有较短的文本。
有没有办法用 Godot 布局工具来实现这一点?
A Button
in Godot can only hold a single line of text. I can overcome this limitation by placing RichTextLabel
node inside the button.
Now the button can contain more lines of text, but its height doesn't change automatically when more lines are needed. Instead the text just overflows:
Of course I can manually resize the button to be higher, but I'd like this to happen automatically depending on the amount of text inside. Specifically, I'm generating a list of these buttons programmatically and showing inside a HBoxContainer
, with some buttons having longer and other shorter text.
Is there a way to achieve this with Godot layout tools?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
(Godot 3.x)
在不使用脚本的情况下,也可以通过将两个节点作为同级节点包装在容器(例如 MarginContainer)内来实现相同的目标。启用 RichTextLabel 的
fit_content_height
属性,这将导致标签根据需要扩展容器区域,进而调整 Button 的大小。(Godot 3.x)
Without using scripting, it is also possible to achieve the same goal by wrapping both nodes as sibilings within a container, for example a MarginContainer. Enable the RichTextLabel's
fit_content_height
property, which will result in the label expanding the container's area as much as necessary, which will in turn resize the Button.(Godot 4.1.1)我今天尝试实现相同的功能,您可以通过使用节点来实现:
创建一个
PanelContainer
并添加一个按钮节点及其内部的标签。您可以调整它们的大小,直到您满意为止。将标签的自动换行模式设置为“Word(智能)”。
将
PanelContainer
的大小调整为您想要的尺寸。现在您会注意到,当您调整
PanelContainer
大小时,按钮和标签都会动态调整其大小以适合PanelContainer
。我希望这对任何阅读的人都有帮助。(Godot 4.1.1)I try to realize the same function today,you can achieve this by using nodes:
Create a
PanelContainer
and add a button node along with a label inside it. You can adjust their sizes until you are satisfied.Set the label's AutoWrap Mode to "Word (Smart)".
Adjust the size of the
PanelContainer
to your desired dimensions.Now you will notice that when you resize the
PanelContainer
, both the button and the label will dynamically adjust their sizes to fit within thePanelContainer
. I hope this is helpful for anyone reading.Godot 4.3 现在为“文本行为”下的按钮提供了自动换行模式
Godot 4.3 now has auto-wrap mode for buttons under "Text Behavior"
由于
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
的宽度,您可以读取它的高度,并使用它来设置Button
的高度按钮
的>rect_min_size。还有一件事:您需要将
RichTextLabel
的鼠标过滤器设置为“忽略”或“通过”,否则它将阻止按下Button
。这是我想出的代码:
遗憾的是更改文本不会调整大小,也不会更改
RichTextLabel
的最小大小。并且RichTextLabel
没有“文本已更改”信号。也没有“bbcode 文本已更改”信号。此外,拦截这些属性可能不可行(请参阅append_bbcode
等)。 使用常规标签可能更容易。无论如何,我建议制作一个包装
RichTextLabel
Control code>,提供您实际需要的任何界面,并且在更改文本的任何方法中,之后您可以执行与此等效的操作:Since the
Button
is in aContainer
, it is in control of itsrect_size
. The best we can do is specify arect_min_size
. There is no layout preset to have aControl
depend on childrenControl
. So, to answer the question as posted: No, we cannot achieve this with Godot layout tools. We need some scripting.We need to set the
rect_min_size
for theButton
depending on theRichTextLabel
. We can ask it for the height of its content withget_content_height
. Which also means we need to set the width beforehand. However, it will not update right away when we set the text (we are going to useyield
).Apparently you don't want the
Container
to control the height of theButton
. If that is the case, I think you can remove all the flags fromsize_flags_vertical
.About the width, since as I was explaining before we need to set the width to get the height… I suggest you let the
Container
expand the width of theButton
as much a posible. Which mean setting both the Fill and Expand flags onsize_flags_horizontal
.Then, with the
RichTextLabel
properly set to take as much width of the parentButton
as possible, you can read it height, and use it to set the height of therect_min_size
of theButton
.One more thing: you want to set the mouse filter of the
RichTextLabel
to Ignore or Pass, or it will prevent pressing theButton
.This is the code I came up with:
Sadly changing the text does not resize, nor change the minimum size of the
RichTextLabel
. AndRichTextLabel
does not have a "text changed" signal. Nor "bbcode text changed" signal. Furthermore, it might not be feasible to intercept these properties (seeappend_bbcode
et.al). It is proabaly easier to do with a regular Label.Anyway, what I'm going to suggest for this is to make a
Control
that wraps theRichTextLabel
, offers whatever interface you actually need, and in any method where you change the text, afterwards, you do the equivalent of this: