Work in progress
The content of this page was not yet updated for Godot 4.2
and may be outdated. If you know how to improve this page or you can confirm that it’s up to date, feel free to open a pull request.
自定义 GUI 控件
控件真多呀……
不过这是永远不嫌多的。每个 GUI 程序员几乎都痴迷于创建自己的自定义控件,让这些控件让自己的要求工作。Godot 提供了大量的控件,但它们可能并不完全如你所愿的方式工作。在使用支持对角滚动条的拉取请求与开发人员联系之前,至少应该了解如何从脚本轻松地创建这些控件。
绘制
谈到绘制, 推荐看看这篇 2D 中的自定义绘图 的教程. 同样的原理适用与控件绘制. 这里有些函数值得一提, 因为它们在绘制时有用, 所以接下来将进行详细说明:
检查控件的大小
Unlike 2D nodes, “size” is important with controls, as it helps to organize them in proper layouts. For this, the Control.size property is provided. Checking it during _draw()
is vital to ensure everything is kept in-bounds.
检查输入焦点
一些控件(如按钮或文本编辑器)可为键盘或手柄输入提供输入焦点. 这方面的例子是输入文本或按下一个按钮. 这可以通过 Control.focus_mode 属性来控制. 绘制时, 如果控件支持输入焦点, 总是希望显示某种指示来表明(高亮, 方框等), 当前这是焦点控件. 为了检查这个状态, 存在一个 Control.has_focus() 的方法. 例子
GDScriptC#
func _draw():
if has_focus():
draw_selected()
else:
draw_normal()
public override void _Draw()
{
if (HasFocus())
{
DrawSelected()
}
else
{
DrawNormal();
}
}
调整大小
如前所述, 尺寸对控件是很重要的. 这可以让它们在设置网格, 容器或锚定时以正确布局. 控件, 在大多数情况下, 提供了一个 minimum size , 以帮助它们正确布局. 例如, 如果控件被垂直放置在彼此的顶部, 使用 VBoxContainer , 最小尺寸将确保你的自定义控件不会被容器中的其他控件挤压.
To provide this callback, just override Control._get_minimum_size(), for example:
GDScriptC#
func _get_minimum_size():
return Vector2(30, 30)
public override Vector2 _GetMinimumSize()
{
return new Vector2(20, 20);
}
或者, 使用函数进行设置:
GDScriptC#
func _ready():
set_custom_minimum_size(Vector2(30, 30))
public override void _Ready()
{
SetCustomMinimumSize(new Vector2(20, 20));
}
输入
控件为输入事件的管理提供了一些辅助工具,比普通节点要方便一点。
输入事件
在此之前有几个关于输入的教程, 但值得一提的是, 控件有一个特殊的输入方法, 只有在以下情况下才起作用:
鼠标指针悬停在控件上.
鼠标按键在此控件上被按下 (控件始终捕获输入, 直到按钮被释放)
控件通过以下方式提供键盘和手柄焦点 Control.focus_mode.
This function is Control._gui_input(). Simply override it in your control. No processing needs to be set.
GDScriptC#
extends Control
func _gui_input(event):
if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
print("Left mouse button was pressed!")
public override void _GuiInput(InputEvent @event)
{
if (@event is InputEventMouseButton mbe && mbe.ButtonIndex == MouseButton.Left && mbe.Pressed)
{
GD.Print("Left mouse button was pressed!");
}
}
有关事件本身的详细信息,请查看 使用 InputEvent 教程。
通知
控件也有许多有用的通知, 这些通知不存在专门的回调, 但可以用_notification回调来检查:
GDScriptC#
func _notification(what):
match what:
NOTIFICATION_MOUSE_ENTER:
pass # Mouse entered the area of this control.
NOTIFICATION_MOUSE_EXIT:
pass # Mouse exited the area of this control.
NOTIFICATION_FOCUS_ENTER:
pass # Control gained focus.
NOTIFICATION_FOCUS_EXIT:
pass # Control lost focus.
NOTIFICATION_THEME_CHANGED:
pass # Theme used to draw the control changed;
# update and redraw is recommended if using a theme.
NOTIFICATION_VISIBILITY_CHANGED:
pass # Control became visible/invisible;
# check new status with is_visible().
NOTIFICATION_RESIZED:
pass # Control changed size; check new size
# with get_size().
NOTIFICATION_MODAL_CLOSE:
pass # For modal pop-ups, notification
# that the pop-up was closed.
public override void _Notification(int what)
{
switch (what)
{
case NotificationMouseEnter:
// Mouse entered the area of this control.
break;
case NotificationMouseExit:
// Mouse exited the area of this control.
break;
case NotificationFocusEnter:
// Control gained focus.
break;
case NotificationFocusExit:
// Control lost focus.
break;
case NotificationThemeChanged:
// Theme used to draw the control changed;
// update and redraw is recommended if using a theme.
break;
case NotificationVisibilityChanged:
// Control became visible/invisible;
// check new status with is_visible().
break;
case NotificationResized:
// Control changed size; check new size with get_size().
break;
case NotificationModalClose:
// For modal pop-ups, notification that the pop-up was closed.
break;
}
}
© 版权所有 2014-present Juan Linietsky, Ariel Manzur and the Godot community (CC BY 3.0). Revision b1c660f7
.
Built with Sphinx using a theme provided by Read the Docs.