解决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
相关产品推荐
相关产品推荐

