TDIL: The Magic of Callable.bind in GDScript
Today I learned (TDIL) about a super helpful feature in GDScript: Callable.bind. If you’re working with signals in Godot and find yourself needing to pass additional data to a single handler, Callable.bind is your new best friend.
The Problem
In many UI setups, you might have multiple buttons that trigger the same function. However, these buttons often represent different actions or carry unique context. For example: A list of character abilities with each button corresponding to a specific skill. A menu system where each button navigates to a different scene or executes a unique task. The usual approach is to connect each button’s pressed signal to the same function. But how do you tell which button triggered the signal? And what if you need to pass more data (e.g., an ID, name, or reference) to your handler?
The Solution: Callable.bind
Callable.bind allows you to attach additional arguments to a function call. This means you can make your signal handler more dynamic without writing extra boilerplate code.
The Button.button_up
signal doesn’t allow any arguments to be returned to the handler function, so we solve this by binding data.
Let’s break it down with an example:
func create_chracter_button(character: Networking.Proto.Entiy) -> Button:
var button: Button = Button.new()
button.text = character.get_name()
button.size.y = 100
button.button_up.connect(on_character_button_released.bind(character))
return button
func on_character_button_released(character: Networking.Proto.Entiy) -> void:
print(character.get_name() + " selected")
current_character = character
%CharacterName.clear()
%CharacterName.text = "[center][b]" + character.get_name() + "[/b][/center]"