【Godot4.2】菜单栏生成函数库menuDB

概述

关于Godot的手动菜单栏制作,我已经在之前的文章中有所描述。

但是对于一些场景,手动制作菜单仍然是一个比较低效的做法。所以我将MenuBar以及基于HBoxContainer+MenuButton创建菜单栏写成了一个静态函数库。

利用此函数库我们可以用函数形式构造PopupMenuMenuButtonMenuBar以及基于HBoxContainer+MenuButton创建的菜单栏。

另外我自定义3种资源,来定义和存储单个菜单栏、单个菜单和单个菜单项所需的数据:

  • MenuBarData:存储定义单个MenuBar所需的数据
  • MenuData:存储定义单个菜单所需的数据
  • PopupMenuItem:存储单个菜单项所需的数据

当然我的本意是基于这个函数库构建更简单的菜单栏自定义控件。

函数库代码

# ========================================
# 名称:menuDB
# 类型:静态函数库
# 描述:专用于【生成菜单栏】的静态函数库
# 作者:巽星石
# Godot版本:v4.2.1.stable.official [b09f793f5]
# 创建时间:202422718:45:28
# 最后修改时间:202422721:51:11
# ========================================
class_name menuDB# -------------- 构造MenuBar或基于HBoxContainer+MenuButton的水平菜单栏 --------------
# 构造并返回有完整结构的MenuBar
static func menu_bar(menu_bar_data:MenuBarData) -> MenuBar:var bar = MenuBar.new()# 遍历MenuBar数据,创建PopUpfor menu_data in menu_bar_data.menus:var menu = popup_menu(menu_data.text,menu_data.items,menu_bar_data.icon_max_width)bar.add_child(menu)return bar# 构造并返回多个MenuButton水平排列的HBoxContainer
static func hbox_menu_bar(menu_bar_data:MenuBarData) -> HBoxContainer:var bar = HBoxContainer.new()# 遍历MenuBar数据,创建PopUpfor menu_data in menu_bar_data.menus:var menu = menu_button(menu_data.text,menu_data.icon,menu_data.items,menu_bar_data.icon_max_width)bar.add_child(menu)return bar# -------------- 构造 PopupMenuMenuButton --------------
# 构造并返回一个带有菜单项的PopupMenu
static func popup_menu(text:String = "MenuButton",  # 按钮文本items:Array[PopupMenuItem] = [], # 菜单项数据集items_icon_max_width = 16        # 菜单项图标的最大宽度) -> PopupMenu:# --------------- 创建MenuButton ---------------var menu = PopupMenu.new()menu.name = text# --------------- 遍历items,为PopupMenu添加菜单项 ---------------for item in items:popup_menu_add_item(menu,item,items_icon_max_width)return menu# 构造并返回带有菜单项的MenuButton
static func menu_button(text:String = "MenuButton",  # 按钮文本icon:Texture2D = null,           # 按钮图标items:Array[PopupMenuItem] = [], # 菜单项数据集items_icon_max_width = 16        # 菜单项图标的最大宽度) -> MenuButton:# --------------- 创建MenuButton ---------------var btn = MenuButton.new()btn.text = textbtn.icon = icon# --------------- 获取其PopupMenu ---------------var menu:PopupMenu = btn.get_popup()# --------------- 遍历items,为PopupMenu添加菜单项 ---------------for item in items:popup_menu_add_item(menu,item,items_icon_max_width)return btn# -------------- PopupMenu菜单项添加 --------------
# 通过PopupMenuItem资源数据为PopupMenu添加一个菜单项
static func popup_menu_add_item(menu:PopupMenu,item:PopupMenuItem,icon_max_width = 16) -> void:var index = menu.item_count # 当前项索引 = 已有菜单项总数# 创建纯文本菜单项menu.add_item(item.text)# 设置附加选项if item.icon:              # 图标menu.set_item_icon(index,item.icon)menu.set_item_icon_max_width(index,icon_max_width)        # 图标最大宽度if item.checkable:         # 复选框 形式menu.set_item_as_checkable(index,item.checkable)if item.radio_checkable:   # 单选框 形式menu.set_item_as_radio_checkable(index,item.radio_checkable)if item.separator:         # 带分割线 形式menu.set_item_as_separator(index,item.separator)if item.shortcut:          # 快捷键 + 是否全局menu.set_item_shortcut(index,item.shortcut,item.shortcut_global)menu.set_item_shortcut_disabled(index,item.shortcut_disabled)   # 快捷键是否禁用menu.set_item_checked(index,item.checked)    # 是否选中(仅在单选框或复选框形式下)menu.set_item_disabled(index,item.disabled)  # 是否禁用menu.set_item_tooltip(index,item.tooltip)    # 鼠标提示文本if item.sub_menu.size() > 0:        # 如果菜单项存在子菜单项var sub_popup = PopupMenu.new() # 创建子菜单sub_popup.name = "%d_%s_sub_popup" % [index,item.text]  # 创建唯一名称# 添加子菜单项for sub_item in item.sub_menu:popup_menu_add_item(sub_popup,sub_item,icon_max_width)# 添加为当前PopupMenu的子节点menu.add_child(sub_popup)menu.set_item_submenu(index,sub_popup.name)  # 为当前项指定子菜单的名称

3种自定义数据结构

MenuBar

@tool
# 单个MenuBar数据
class_name MenuBarData extends Resource@export var menus:Array[MenuData]           # 菜单列表
@export var icon_max_width = 16       # 菜单项图标的最大宽度

MenuData

@tool
# 单个菜单数据
class_name MenuData extends Resource@export var text:String                     # 按钮文本
@export var icon:Texture2D                  # 按钮图标
@export var items:Array[PopupMenuItem]      # 菜单项

PopupMenuItem

@tool
# PopupMenu单个菜单项数据
class_name PopupMenuItem extends Resource# 基础设置
@export var text:String             # 文本
@export var icon:Texture2D          # 图标
# 特殊形式
@export var checkable:bool          # 复选框 形式
@export var radio_checkable:bool    # 单选框 形式
@export var separator:bool          # 带分割线 形式
# 快捷键
@export var shortcut:Shortcut       # 快捷键
@export var shortcut_global:bool    # 快捷键是否全局
@export var shortcut_disabled:bool  # 快捷键是否禁用
# 选中与禁用
@export var checked:bool            # 选中
@export var disabled:bool           # 禁用
# 鼠标提示文本
@export var tooltip:String          # 鼠标提示文本
# 子菜单
@export var sub_menu:Array[PopupMenuItem]     # 子菜单

基于函数库创建自定义MenuBar节点

# ========================================
# 基于menuDB函数库的自定义MenuBar节点
# ========================================
@tool
class_name myMenuBar extends MenuBar@export var data:MenuBarData:set(val):data = valcreate()# 根据MenuBarData创建菜单和菜单项
func create() -> void:# 遍历MenuBar数据,创建PopUpfor menu_data in data.menus:var menu = menuDB.popup_menu(menu_data.text,menu_data.items,data.icon_max_width)add_child(menu)

我们可以看到myMenuBar类型有一个Data参数,我们需要为其设定MenuBarData类型的资源。
在这里插入图片描述
运行后的效果如下:
在这里插入图片描述
可以看到这种自定义资源多层嵌套形式在Godot检视器面板上就是一种灾难。

所以更好的做法是基于字典的解析。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2813644.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

前后端分离vue+php仓库管理系统 n2bm6

1.功能需求 (1)系统功能包括 :产品入出库登记、确认入出库信息、删除库内信息、借出信息登记、产品分类管理、,报表生成,事件记录,数据检测、数据警告。 (2)系统管理员功能&#xf…

基于JSP的毕业设计选题系统的设计与实现

基于JSP的毕业设计选题系统的设计与实现 (源代码论文) A. 项目简介 毕业设计选题系统就是能够使学生通过互联网完成毕业设计课题的选定,它采用Web方式,同时适用于局域网和Internet,它要实现审核,权限管理,邮件通知…

C# OpenCvSharp DNN Yolov8-OBB 旋转目标检测

目录 效果 模型信息 项目 代码 下载 C# OpenCvSharp DNN Yolov8-OBB 旋转目标检测 效果 模型信息 Model Properties ------------------------- date:2024-02-26T08:38:44.171849 description:Ultralytics YOLOv8s-obb model trained on runs/DOT…

有适合短视频剪辑软件的吗?分享4款热门软件!

在数字时代,短视频已成为人们获取信息、娱乐消遣的重要形式。随着短视频行业的蓬勃发展,市场上涌现出众多短视频剪辑软件,它们功能各异,各具特色。本文将为您详细介绍几款热门短视频剪辑软件,助您轻松掌握短视频剪辑技…

BIO实战、NIO编程与直接内存、零拷贝深入辨析

BIO实战、NIO编程与直接内存、零拷贝深入辨析 长连接、短连接 长连接 socket连接后不管是否使用都会保持连接状态多用于操作频繁,点对点的通讯,避免频繁socket创建造成资源浪费,比如TCP 短连接 socket连接后发送完数据后就断开早期的http服…

phpldapadmin This base cannot be created with PLA

phpldapadmin This base cannot be created with PLA 1、问题描述2、问题分析3、解决方法:创建根节点 1、问题描述 安装phpldapadmin参考链接: https://blog.csdn.net/OceanWaves1993/article/details/136048686?spm1001.2014.3001.5501 刚安装完成phpldapadmin&…

MyCAT从入门到实战(MyCAT2注释配置)

重置配置 /* mycat:resetConfig{} */; 用户相关 创建用户 /* mycat:createUser{ "username":"user", "password":"", "ip":"127.0.0.1", "transactionType":"xa"} */; 删除用户 /* myc…

软件License授权原理

软件License授权原理 你知道License是如何防止别人破解的吗?本文将介绍License的生成原理,理解了License的授权原理你不但可以防止别人破解你的License,你甚至可以研究别人的License找到它们的漏洞。喜欢本文的朋友建议收藏关注,…

Maya笔记 设置工作目录

Maya会把素材场景等自动保存在工作目录里,我们可以自己定义工作目录 步骤1 创建workspace.mel文件 文件/设置项目 ——>选择一个文件夹,点击设置——>创建默认工作区 这一个后,可以在文件夹里看到.mel文件 步骤2 自动创建文件夹…

华为OD机试真题-靠谱的车-2023年OD统一考试(C卷)---Python3-开源

题目: 考察内容: 思维转化,进制转化,9进制转为10进制,在4的位置1,需要判断是否大于4 代码: """ 题目分析: 9进制转化为10进制23-25 39-50 399-500输入&#xff1a…

Qt的QThread、QRunnable和QThreadPool的使用

1.相关描述 随机生产1000个数字,然后进行冒泡排序与快速排序。随机生成类继承QThread类、冒泡排序使用moveToThread方法添加到一个线程中、快速排序类继承QRunnable类,添加到线程池中进行排序。 2.相关界面 3.相关代码 widget.cpp #include "widget…

安防视频汇聚EasyCVR视频云存储平台GB28181设备全部离线是什么原因?

众所周知,安防视频汇聚平台EasyCVR不仅可支持的接入协议非常多(包括:国标GB28181、RTSP/Onvif、RTMP,以及厂家的私有协议与SDK,如:海康ehome、海康sdk、大华sdk、宇视sdk、华为sdk、萤石云sdk、乐橙sdk等&a…

日更【系统架构设计师知识总结3】存储系统

【原创精华总结】自己一点点手打、总结的脑图,把散落在课本以及老师讲授的知识点合并汇总,反复提炼语言,形成知识框架。希望能给同样在学习的伙伴一点帮助!

Nginx——安装和反向代理

Nginx安装与应用 1.1 Nginx介绍 Nginx 是一个高性能的HTTP和反向代理服务器,特点是占有内存少,并发能力强 Nginx可以作为静态页面的web服务器,同时还支持CGI协议的动态语言,比如perl、php等。但是不支持java。Java程序只能通过与tomcat配合…

CentOS 7全系列免费

CentOS 7 全系列免费:桌面版、工作站版、服务器版等等………… 上文,关于CentOS 7这句话,被忽略了。 注意版本:知识产权、网络安全。

嵌入式学习第二十二天!(继续学习线程)

线程相关函数接口: 1. 线程分离属性: 线程结束后,自动回收线程空间 1. pthread_attr_init: int pthread_attr_init(pthread_attr_t *attr); 功能:线程属性初始化 2. pthread_attr_destroy: int pthread_…

【Godot4自学手册】第十七节主人公的攻击和敌人的受伤

本节主要学习主人公是如何向敌人发起进攻的,敌人是如何受伤的,受伤时候动画显示,击退效果等。其原理和上一节内容相同,不过有许多细节需要关注和完善。 一、修改Bug 在本节学习之前,我将要对上一节的代码进行完善&am…

【C语言】while循环语句

🎈个人主页:豌豆射手^ 🎉欢迎 👍点赞✍评论⭐收藏 🤗收录专栏:C语言 🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共同学习、交流进步&…

蓝桥杯备战刷题two(自用)

1.杨辉三角形 #include<iostream> using namespace std; #define ll long long const int N2e510; int a[N]; //1 0 0 0 0 0 0 //1 1 0 0 0 0 0 //1 2 1 0 0 0 0 //1 3 3 1 0 0 0 //1 4 6 4 1 0 0 //1 5 10 10 5 1 //前缀和思想 //第一列全为1,第二列为从0开始递增1的序…

汇总版!美团搜索推荐算法面试题10道(含答案)

节前&#xff0c;我们组织了一场算法岗技术&面试讨论会&#xff0c;邀请了一些互联网大厂同学、参加社招和校招面试的同学&#xff0c;针对算法岗技术趋势、大模型落地项目经验分享、新手如何入门算法岗、该如何准备、面试常考点分享等热门话题进行了深入的讨论。 今天我整…