Game development is an exciting journey, full of interesting twists and turns. One such twist is the understanding and use of various classes within a game engine. Today, we’ll dive into the class PopupMenu in Godot 4. This class plays a pivotal role in creating interactive menus in your games, making it an essential tool in your game development toolkit.
Table of contents
What is PopupMenu?
The PopupMenu class in Godot 4 is a specialized class that enables developers to create and manage interactive menus in their games. These menus can be used for various purposes like game settings, character selection, or even in-game purchases.
Why should I learn it?
Learning and understanding the PopupMenu class will empower you to create more dynamic and interactive games. It adds a layer of user engagement that can enhance the overall gaming experience. Therefore, mastering this class is highly beneficial for both aspiring and experienced game developers.
Developer API
To explore the PopupMenu class in detail and understand its full potential, we recommend visiting the official Godot 4 documentation. Get a deep dive into its methods, properties, and signals by clicking here.
Example Project
You can download the project files here.
In this example, we will be recreating a popup menu similar to the menu that appears when you click on one of the buttons on the top right section of the godot editor.

That menu bar in the editor uses a combination of a MenuBar node with PopupMenu nodes, however for the sake of this example, we will simply be looking at how to set up a single PopupMenu.
Lets take a look at how we can customize and interact with the options of a PopupMenu!
To begin with, lets create a new PopupMenu node in our scene. You will noticed that it is invisible, we can see what it looks like by pressing on the eye icon on the node in the scene tree, or checking the ‘Visible’ option under the ‘Flags’ dropdown in the inspector.
We can use the position property to position the window correctly. Note that you will not be able to interact with this window in the 2D viewport, this is because the node inherits Window and not CanvasItem.
Simple breakdown of an item
Similar to an ItemList node, this node also has an ‘Items’ dropdown that we can add elements to. Press on the ‘Add Element’ button to add a new item to the PopupMenu.
Each item can have a Text label, an Icon, and an ID.
Note that the icon cannot be scaled individually, so you will need to provide the icon at the right size.
Using the Checkable property, you are able to turn the item into either of the following:
- Checkbox toggle: Could be used for simple on/off states.
- Radio button: Could be used to present a set of mutually exclusive options to choose one of.
These can be checked on and off using the Checked property.
You could set an empty item’s Seperator property to turn it into a seperator to visually seperate items.
You could also have an item that opens another new popup menu as a submenu! (This can only be done through code).
We also have the a couple of properties available to us to customize the behaviour of the PopupMenu:
hide_on_item_selection: Turns off visibility when a normal item is selected.
hide_on_checkable_item_selection: Turns off visibility when a Checkbox/Radio button is pressed.
submenu_popup_delay: The delay when a submenu is spawned.
Creating the items dynamically
We can set up different items by creating them in the editor with the ‘Add Element’ button and using the item’s properties that were discussed above, which should be fairly straightforward. Note that the sub item popups can only be made through code. (It will be discussed below in this example)
Let’s create a script on the PopupMenu node. We can use the various add_* methods in the PopupMenu class to add different types of items to our PopupMenu.
add_item() can be used to add a simple item with just a label.
add_check_item() can be used to add an item with a checkbox.
add_icon_check_item() can be used to ad an item with a checkbox and an icon.
These are just a couple of examples out of many others available to us. Check the method list in the official documentation for the PopupMenu class for a comprehensive list.
Let us use some these methods to create some items.
extends PopupMenu
func _ready():
add_item("Simple item")
add_check_item("Check item")
add_separator()
add_radio_check_item("Radio check item")When we run the game, we should see some new items it our PopupMenu!
Creating a Submenu item
We can use the add_submenu_item() method to do this. For this to work, we need to first create a new PopupMenu node as a child of the one we already have. Click on the existing PopupMenu node and press Ctrl + A to create a new node, select PopupMenu to add it as a child. Let’s rename it to “ExampleSubmenu” and create 2 new items called “Submenu Item 1” and “Submenu Item 2”.
When using add_submenu_item(), we can give the item a text label just like a normal item, however we will also need to pass in the name of the submenu node we just created as the second argument. Note that it will need to be called with the exact name of the node (Here, “ExampleSubmenu”).
func _ready():
#previous code
add_submenu_item("Submenu example", "ExampleSubmenu")When we add this method call to ready and run the game, we should see a new item show up with the label we provide in the first parameter, when we hover over or click on this item, we see the submenu automatically appear!

The submenu_popup_delay property determines the delay for the submenu to show up, you can set this in the inspector if you like.
Interacting with the PopupMenu
You may have noticed that clicking on an item does not do anything. The PopupMenu node emits some helpful signals when the node is interacted with, which we can connect to, to define custom logic.
One such signal is the index_pressed signal, which passes the index that was pressed as an argument. We can check against this index to run specific logic in the signal handler.
Lets connect to the signal in ready and print messages for indices 0 (Simple item) and 1 (Check item).
Set the hide_on_checkable_item_selection property to false in the inspector so that the PopupMenu does not disappear when the Check item is pressed.
func _ready():
index_pressed.connect(_on_index_pressed)
func _on_index_pressed(index: int):
if index == 0:
print("Simple item was pressed!")
elif index == 1:
print("Check item was pressed!")We should now see the correct message being printed to the output when the corresponding items are clicked!
When we click the Check item, the message is printed, but you will see that the item itself does not get visibly checked. This is because the node does not handle that automatically, we will need to handle that ourself. When the check item is pressed, we can call the toggle_item_checked() method and pass in the index to check it visibly.
We can use the is_item_checked() method which returns a bool to be able to run different logic based on whether the item was checked or unchecked. Let us modify our code to take this into account.
func _on_index_pressed(index: int):
if index == 0:
print("Simple item was pressed!")
elif index == 1:
toggle_item_checked(1)
if is_item_checked(1):
print("Check item was CHECKED!")
else:
print("Check item was UNCHECKED!")Setting item properties after creation
Similar to the toggle_item_checked() method, which modifies the Checked property of an item, there are other helper method that are available to us to modify item properties.
For example:
set_item_text(): Can be used to dynamically change an item’s label.
set_item_submenu(): Can be used to turn a pre-existing item into a submenu item.
This should give you an idea of how to interact with the PopupMenu node! We’ve only just scratched the surface on what is possible, it is recommended that you take a look at the official documentation for the PopupMenu class to get a full idea list of helper methods and functionality! Good luck!
Full script code
You can download the Godot project here. The project was developed and tested in version 4.2.
extends PopupMenu
func _ready():
add_item("Simple item")
add_check_item("Check item")
add_separator()
add_radio_check_item("Radio check item")
add_submenu_item("Submenu example", "ExampleSubmenu")
index_pressed.connect(_on_index_pressed)
func _on_index_pressed(index: int):
if index == 0:
print("Simple item was pressed!")
elif index == 1:
toggle_item_checked(1)
if is_item_checked(1):
print("Check item was CHECKED!")
else:
print("Check item was UNCHECKED!")Where to go next?
Exploring the nuances of game development is an ongoing journey, and we at Zenva are here to guide you every step of the way. We encourage you to continue deepening your knowledge and honing your skills. A fantastic next step would be to check out our Godot Game Development Mini-Degree.
This comprehensive learning pathway is designed for aspiring game developers of all skill levels. It is focused on the free, open-source Godot 4 engine, and covers a wide range of game development topics, from 2D and 3D game creation to complex gameplay mechanics across various genres. The program offers an engaging and flexible curriculum, with video lessons, downloadable course materials, and interactive content all available at your own pace.
For a more broad collection and to continue your learning journey, feel free to explore our Godot courses at Zenva. Remember, with us, you can go from beginner to professional. Happy coding!
Did you come across any errors in this tutorial? Please let us know by completing this form and we’ll look into it!

FINAL DAYS: Unlock coding courses in Unity, Godot, Unreal, Python and more.







