Godot 4:代码生成单选按钮数组并修复信号关联异常问题
问题原因
你遇到的问题是变量作用域导致的引用覆盖:在循环创建按钮时,button变量未用var声明,属于函数内的全局变量,每次循环都会覆盖它的引用。当信号触发时,_on_button_pressed里的button指向的是最后一次循环创建的按钮,所以无论点击哪个按钮,都会打印最后一个的编号。
解决方案
有两种简单的修复方式:
方法1:绑定按钮实例到信号回调
修改信号连接逻辑,把当前按钮实例作为参数绑定到回调函数,确保每次触发时能直接拿到对应的按钮:
signal button_pressed func create_radio_button_matrix(): var row_count = len(Global.players) - 1 var index = Global.players.find(Global.active_player) var players = Global.players.duplicate() players.pop_at(index) for player in players: for row in row_count: var group = ButtonGroup.new() # 加var声明局部变量,避免全局污染 for col in 4: var button = Button.new() # 关键:用var声明局部变量,防止引用覆盖 gray_foreground.add_child(button) button.set_button_group(group) button.position = Vector2(200 + 100 * col, 150 + 35 * row) button.size = Vector2(95, 20) button.toggle_mode = true button.action_mode = BaseButton.ACTION_MODE_BUTTON_PRESS button.text = str(row * 4 + col) # 将当前按钮绑定到回调函数 button.pressed.connect(_on_button_pressed.bind(button)) if col == 1: button.set_pressed_no_signal(true) func _on_button_pressed(pressed_button): print("Button " + pressed_button.text + " was pressed.")
方法2:在回调中获取信号发射源
如果不想绑定参数,可以在回调函数里直接获取触发信号的按钮节点(注意Godot版本差异):
signal button_pressed func create_radio_button_matrix(): var row_count = len(Global.players) - 1 var index = Global.players.find(Global.active_player) var players = Global.players.duplicate() players.pop_at(index) for player in players: for row in row_count: var group = ButtonGroup.new() for col in 4: var button = Button.new() gray_foreground.add_child(button) button.set_button_group(group) button.position = Vector2(200 + 100 * col, 150 + 35 * row) button.size = Vector2(95, 20) button.toggle_mode = true button.action_mode = BaseButton.ACTION_MODE_BUTTON_PRESS button.text = str(row * 4 + col) button.pressed.connect(_on_button_pressed) if col == 1: button.set_pressed_no_signal(true) func _on_button_pressed(): # Godot 3.x 使用该行 var pressed_button = get_signal_emitter() # Godot 4.x 替换为:var pressed_button = get_emitter() print("Button " + pressed_button.text + " was pressed.")
额外注意
循环中的group变量也必须用var声明,否则会变成全局变量,导致所有按钮被分配到最后一个按钮组,破坏单选按钮的分组功能。
内容的提问来源于stack exchange,提问作者Ian McCurdy
相关产品推荐
相关产品推荐

