You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 22:42:26