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

Pygame按钮切换图片报错:TypeError:参数1需为pygame.Surface而非str

Fixing "TypeError: argument 1 must be pygame.Surface, not str" in Your Pygame Button System

Hey there! Let's get that button issue sorted out. You nailed the root cause—you're passing string identifiers like 'default_ip' to your button_img function, but it expects actual pygame.Surface objects (the ones you loaded with pygame.image.load()).

Here's how to fix this cleanly:

1. Use a Dictionary to Map Names to Your Button Surfaces

First, create a dictionary that stores your pre-loaded button surfaces using the name strings (like "default" or "chewbacca") as keys. This lets you look up the right surfaces easily without messing with string concatenation:

# Load your images first (keep this part)
default_ap = pygame.image.load('button_menu_ap.png')
default_ip = pygame.image.load('button_menu_ip.png')
chewbacca_ip = pygame.image.load('button_select_GalaxyWars_chewbacca_ip.png')
chewbacca_ap = pygame.image.load('button_select_GalaxyWars_chewbacca_ap.png')

# Create a dictionary to map names to surface pairs (ip, ap)
button_surfaces = {
    "default": (default_ip, default_ap),
    "chewbacca": (chewbacca_ip, chewbacca_ap)
}

2. Update the select_p1 Function to Use the Dictionary

Instead of building string names, pull the actual surfaces from the dictionary. Also, note that the pygame.display.update() line after your return won't ever run—return exits the function immediately, so we can remove that:

def select_p1(nombre):
    # Get the (ip, ap) surface pair from the dictionary
    nombre_ip, nombre_ap = button_surfaces[nombre]
    # Call button_img with the actual surfaces, not strings
    button_img(display_weight/2-300, display_height/2-250, 100, 100, nombre_ip, nombre_ap, select_categoria, 1, nombre)
    pygame.display.update()

3. Fix a Hidden Bug in select_categoria

You've got a variable named select_categoria inside the function that shares the same name as the function itself. This will cause unexpected behavior when you try to use the loop condition. Rename that variable to something like running:

def select_categoria(num):
    global gameDisplay, display_weight, display_height
    # Rename variable to avoid conflict with function name
    running = True
    gameDisplay.fill((255,255,255))
    while running:
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                quit()
            if event.type == VIDEORESIZE:
                display_weight = event.w
                display_height = event.h
                gameDisplay = pygame.display.set_mode((display_weight, display_height), pygame.RESIZABLE)
        # Also, make sure button_select_categoria_ip/ap are loaded and defined!
        button_img(display_weight/2-125, display_height/2-125, 250, 60, button_select_categoria_ip, button_select_categoria_ap, select_GalaxyWars, num)
        pygame.display.update()
        clock.tick(15)

Why This Works

The dictionary acts as a lookup table—when you pass 'default' to select_p1, it grabs the default_ip and default_ap surfaces you loaded earlier, not just strings with those names. This gives button_img the pygame.Surface objects it needs to call gameDisplay.blit() correctly.

One last thing: Make sure all your button surface variables (like button_select_categoria_ip) are properly loaded and defined before you use them in select_categoria—otherwise you'll hit another undefined variable error!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:48:01