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

解决PyGame跨文件共享Surface对象时出现的TypeError: argument 1 must be pygame.Surface错误

解决Pygame跨文件传递Surface对象的TypeError问题

你的问题核心在于:文本文件只能存储字符串,无法直接保存和还原Python对象。当你把screen(一个pygame.Surface实例)转成字符串写入文件时,读回来的只是类似<Surface(1234x123x12 SW)>的文本描述,而非真正的Surface对象,所以调用pygame.draw.rect()时会触发类型错误。

下面是两种可行的修复方案,优先推荐第一种模块化的实现方式:

方案1:模块化调用,直接传递Surface对象(最佳实践)

不要用exec()执行另一个文件的代码,而是把settings.py的逻辑封装成函数,在主程序中导入并直接传递screen对象。这种方式既高效又符合Python的模块化设计。

修改settings.py

把设置界面的逻辑封装成一个可接收screen参数的函数:

import pygame, random, sys
from pygame.locals import *

def run_settings(screen):
    # 用pygame的时间函数替代time.sleep,避免阻塞事件循环
    start_time = pygame.time.get_ticks()
    # 运行2秒后退出设置界面
    while pygame.time.get_ticks() - start_time < 2000:
        # 处理事件,避免窗口假死
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
        # 在传入的screen上绘制图形
        pygame.draw.rect(screen, (255, 255, 255), (random.randint(1, 400), random.randint(1, 400), 10, 10))
        pygame.display.update()
        # 控制帧率,避免占用过多资源
        pygame.time.Clock().tick(60)

修改fish_simulator.py

导入settings模块并调用函数,直接传递screen对象:

import pygame
from pygame.locals import *
import sys
# 将settings所在的目录添加到Python路径(如果不在同一目录)
sys.path.append(r'.\extra programs')
import settings

pygame.init()
flags = RESIZABLE
size_of_monitor = pygame.display.Info()
width = size_of_monitor.current_w - 25
height = size_of_monitor.current_h - 50
screen = pygame.display.set_mode((width, height), flags)

# 后续代码...
if result == 1: # 打开设置界面
    # 直接调用settings的函数,传递screen对象
    settings.run_settings(screen)

方案2:用pickle序列化对象(不推荐,仅作备选)

如果你因为某些原因必须用文件传递对象,可以使用Python的pickle模块,它能将Python对象序列化保存到文件,再反序列化为原对象。不过要注意:pygame的Surface对象序列化可能存在版本兼容性问题,所以仅作为备选方案。

修改fish_simulator.py

用pickle把screen对象写入文件:

import pygame
import pickle
from pygame.locals import *

pygame.init()
flags = RESIZABLE
size_of_monitor = pygame.display.Info()
width = size_of_monitor.current_w - 25
height = size_of_monitor.current_h - 50
screen = pygame.display.set_mode((width, height), flags)

# 后续代码...
if result == 1: # 打开设置界面
    with open(r'files\storage_file.pkl', 'wb') as storage_file:
        pickle.dump(screen, storage_file)
    exec(open(r'.\extra programs\settings.py').read())

修改settings.py

用pickle读取还原Surface对象:

import pygame, random, sys, pickle
from pygame.locals import *

pygame.init()
with open(r'files\storage_file.pkl', 'rb') as storage_file:
    screen = pickle.load(storage_file)

start_time = pygame.time.get_ticks()
while pygame.time.get_ticks() - start_time < 2000:
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
    pygame.draw.rect(screen, (255, 255, 255), (random.randint(1, 400), random.randint(1, 400), 10, 10))
    pygame.display.update()
    pygame.time.Clock().tick(60)

额外提示

  • 避免用time.sleep()阻塞事件循环,这会导致窗口无法响应关闭等操作,改用pygame.time.get_ticks()来控制时长更合理。
  • 尽量使用模块化的代码组织方式,exec()执行外部文件的做法不利于代码维护和调试。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 16:27:34