Pygame项目调用自定义button类正常,菜单跳转时报not callable错误
问题根因
你遇到的报错是典型的变量名与函数名冲突导致的作用域覆盖问题:
- 你在全局作用域定义了名为
lb_easy的菜单跳转函数 - 在
lb_menu函数内部,你创建按钮实例时又使用了lb_easy = button(...)的命名 - Python的变量查找规则中,局部作用域的变量优先级高于全局作用域,因此当你在
lb_menu函数末尾执行lb_easy()时,解释器会把局部的button类实例当成函数调用,自然触发「对象不可调用」的报错。
修复方案
优先推荐通过规范命名解决冲突,避免局部变量覆盖全局函数:
- 将
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()
- 临时解决方案(不推荐):如果不想修改命名,可以在调用时强制指定全局作用域,将
lb_easy()改为globals()['lb_easy'](),但这种写法可读性差,长期维护容易出问题。
内容的提问来源于stack exchange,提问作者Michael G
相关产品推荐
相关产品推荐

