pygame报错video system not initialized的排查与解决
报错含义
pygame.error: video system not initialized 是pygame的通用运行时错误,代表你调用了依赖显示、事件子系统的接口时,对应子系统已经被关闭或未完成初始化。所有窗口创建、画面渲染、事件读取、屏幕刷新操作都需要视频系统处于正常初始化状态才能执行。
问题根因
结合你提供的代码,触发报错的直接原因有两个,另有一个影响运行体验的逻辑缺陷:
- 退出语句位置完全错误:
pygame.quit()被放在while True主循环内部,程序跑完第一轮循环就会执行该语句,强制关闭所有pygame子系统。但主循环并未终止,下一轮循环仍会尝试调用pygame.event.get()、screen.fill()等依赖视频系统的接口,直接抛出错误。 - 事件循环逻辑混乱:事件遍历中的
break缩进错误,加上渲染逻辑被错误放在事件判断的else分支,程序不需要等待文本播放完成、不需要触发10秒延时,只要事件队列出现鼠标移动、窗口激活这类系统自带事件,就会直接跳出事件循环执行退出逻辑,这就是窗口仅闪现0.5秒就关闭的直接原因。 - 存在阻塞主线程的写法:你在
DynamicText.update()中调用time.sleep(10),会直接卡死pygame主线程,等待的10秒内窗口会处于无响应状态,不符合GUI程序的运行规则。
修复方法
按以下规则调整代码即可解决报错,实现预期效果:
- 把
pygame.quit()移到主循环外部,只有确认要退出程序时才执行该语句。 - 重构事件循环逻辑,移除错误位置的
break,把画面填充、绘制、刷新、帧率控制逻辑移到事件循环外部,保证每帧都正常更新画面。 - 删除阻塞主线程的
time.sleep(),改用时间戳记录文本播放完成的时刻,在主循环中判断是否达到10秒间隔,再执行启动外部游戏脚本的逻辑。
修复后的可运行完整代码:
import pygame import time import subprocess pygame.init() screen = pygame.display.set_mode((800, 250)) clock = pygame.time.Clock() font = pygame.font.Font(None, 25) pygame.time.set_timer(pygame.USEREVENT, 200) def text_generator(text): tmp = "" for letter in text: tmp += letter if letter != " ": yield tmp class DynamicText(object): def __init__(self, font, text, pos, autoreset=False): self.done = False self.font = font self.text = text self._gen = text_generator(self.text) self.pos = pos self.autoreset = autoreset self.finish_time = None self.update() def reset(self): self._gen = text_generator(self.text) self.done = False self.finish_time = None self.update() def update(self): if not self.done: try: self.rendered = self.font.render(next(self._gen), True, (0, 128, 0)) except StopIteration: self.done = True self.finish_time = time.time() def draw(self, screen): screen.blit(self.rendered, self.pos) text = "Steve has gone on a quest to defeat the Ender Dragon. Will he make it?" message = DynamicText(font, text, (65, 120), autoreset=True) running = True while running: current_time = time.time() for event in pygame.event.get(): if event.type == pygame.QUIT: running = False if event.type == pygame.USEREVENT: message.update() if message.done and message.finish_time is not None: if current_time - message.finish_time >= 10: subprocess.Popen("python C:\\Users\\david\\Documents\\pythonbook\\pygame1.py 1", shell=True) running = False screen.fill(pygame.color.Color('black')) message.draw(screen) pygame.display.flip() clock.tick(60) pygame.quit()
内容的提问来源于stack exchange,提问作者GMD Dirvelin
相关产品推荐
相关产品推荐

