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

Pygame项目调用自定义button类正常,菜单跳转时报not callable错误

问题根因

你遇到的报错是典型的变量名与函数名冲突导致的作用域覆盖问题:

  • 你在全局作用域定义了名为lb_easy的菜单跳转函数
  • 在lb_menu函数内部,你创建按钮实例时又使用了lb_easy = button(...)的命名
  • Python的变量查找规则中,局部作用域的变量优先级高于全局作用域,因此当你在lb_menu函数末尾执行lb_easy()时,解释器会把局部的button类实例当成函数调用,自然触发「对象不可调用」的报错。
修复方案

优先推荐通过规范命名解决冲突,避免局部变量覆盖全局函数:

  1. 将lb_menu函数内部的按钮实例命名修改为不与全局函数重名的格式,比如给按钮变量统一加btn_前缀,修改后的lb_menu相关代码如下:
def lb_menu():
    running = True
    while running:
        clock.tick(30)
        print("4")
        option = 0
        pygame.display.update()
        # 填充白色背景
        screen.fill(alice_blue)
        # 调用文本绘制函数
        draw_text("Leaderboards", title_font, auro_metal_saurus, screen, screen_width/2, screen_width/10)
        # 创建按钮 修改变量名避免冲突
        btn_lb_easy = button(air_force_blue, (screen_width-300)/2, screen_height*0.25, 300, 50, "Leaderboard - Easy")
        btn_lb_medium = button(air_force_blue, ((screen_width-300)/2), screen_height*0.4, 300, 50, "Leaderboard - Medium")
        btn_lb_hard = button(air_force_blue, ((screen_width-300)/2), screen_height*0.55, 300, 50, "Leaderboard - Hard")
        btn_back = button(air_force_blue, ((screen_width-300)/2), screen_height*0.7, 300, 50, "Back")
        # 绘制按钮
        btn_lb_easy.draw_button(screen)
        btn_lb_medium.draw_button(screen)
        btn_lb_hard.draw_button(screen)
        btn_back.draw_button(screen)
        for event in pygame.event.get():
            pos = pygame.mouse.get_pos()
            if event.type == pygame.QUIT:
                pygame.quit()
                exit()
            if event.type == pygame.MOUSEBUTTONDOWN:
                # 同步修改判断条件里的变量名
                if btn_lb_easy.over_button(pos):
                    option = 1
                    running = False
                elif btn_back.over_button(pos):
                    option = 4
                    running = False
    if option == 1:
        # 此处lb_easy为全局函数,不会再被局部变量覆盖
        lb_easy()
    elif option == 2:
        pass
    elif option == 3:
        pass
    elif option == 4:
        main_menu()
  1. 临时解决方案(不推荐):如果不想修改命名,可以在调用时强制指定全局作用域,将lb_easy()改为globals()['lb_easy'](),但这种写法可读性差,长期维护容易出问题。

内容的提问来源于stack exchange,提问作者Michael G

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 06:36:03