Pygame图灵图案模拟中滑块无法点击且程序卡顿问题求助
问题:Pygame滑块无法工作,程序点击后冻结
我用Pygame写了一段模拟图灵图案的代码,想添加滑块在运行时更新变量,但滑块完全没反应,点击屏幕后程序直接冻结。单独测试pygamewidgets的滑块示例代码是正常的,但集成到自己的代码里就失效了。
原始代码
pygame.init() w_width = 600 w_height = 600 screen = pygame.display.set_mode([w_width, w_height]) ra = 3 ri = 5 wa = 1 wi = 0.2 screen.fill((128, 128, 128)) model = Model(rows,cols, ra, ri, wa, wi, 0.5) model.drawGrid(screen, w_width, w_height) slider_wa = Slider(screen, 40, 20, 50, 10, min=0, max=2, step=0.1) output_wa = TextBox(screen, 5, 10, 25, 25, fontSize=15) output_wa.disable() slider_wi = Slider(screen, 140, 20, 50, 10, min=0, max=2, step=0.1) output_wi = TextBox(screen, 105, 10, 25, 25, fontSize=15) output_wi.disable() slider_ra = Slider(screen, 250, 20, 50, 10, min=0, max=10, step=0.5) output_ra = TextBox(screen, 215, 10, 25, 25, fontSize=15) output_ra.disable() slider_ri = Slider(screen, 360, 20, 50, 10, min=0, max=10, step=0.5) output_ri = TextBox(screen, 325, 10, 25, 25, fontSize=15) output_ri.disable() ra = slider_ra.getValue() ri = slider_ri.getValue() wa = slider_wa.getValue() wi = slider_wi.getValue() running = True time_delay = 100 timer_event = pygame.USEREVENT + 1 pygame.time.set_timer(timer_event, time_delay ) win = pygame.display.set_mode([w_width, w_height]) while running: for event in pygame.event.get(): if event.type == QUIT: running = False if event.type == KEYDOWN: if event.key == K_RIGHT: model.update() model.drawGrid(screen, w_width, w_height) if event.type == timer_event: model.update() model.drawGrid(screen, w_width, w_height) screen.fill((128, 128, 128)) output_wa.setText(slider_wa.getValue()) output_wi.setText(slider_wi.getValue()) output_ra.setText(slider_ra.getValue()) output_ri.setText(slider_ri.getValue()) pygame_widgets.update(event) pygame.display.update() pygame.quit()
问题根源
- 事件处理错误:
pygame_widgets.update(event)放在主循环外,滑块无法接收鼠标事件;且主循环内未将事件传递给widgets处理。 - 重复创建窗口:先后创建
screen和win两个窗口,导致渲染混乱。 - 变量更新缺失:滑块值仅在初始化时读取一次,运行中滑块变动后未同步到模型变量。
- 渲染逻辑位置错误:界面填充、文本更新、屏幕刷新等代码都在主循环外,永远不会执行。
修复后的代码
import pygame from pygame_widgets import Slider, TextBox from pygame.locals import QUIT, KEYDOWN, K_RIGHT # 假设你的Model类已正确实现 class Model: def __init__(self, rows, cols, ra, ri, wa, wi, val): self.rows = rows self.cols = cols self.ra = ra self.ri = ri self.wa = wa self.wi = wi # 其他初始化逻辑 def update(self): # 图灵图案更新逻辑 pass def drawGrid(self, screen, width, height): # 网格绘制逻辑 pass pygame.init() w_width = 600 w_height = 600 # 仅创建一个窗口 screen = pygame.display.set_mode([w_width, w_height]) pygame.display.set_caption("图灵图案模拟") rows = 30 # 根据需求调整行列数 cols = 30 ra = 3 ri = 5 wa = 1 wi = 0.2 screen.fill((128, 128, 128)) model = Model(rows, cols, ra, ri, wa, wi, 0.5) model.drawGrid(screen, w_width, w_height) # 创建滑块与文本框,添加初始值参数 slider_wa = Slider(screen, 40, 20, 50, 10, min=0, max=2, step=0.1, initial=wa) output_wa = TextBox(screen, 5, 10, 25, 25, fontSize=15) output_wa.disable() slider_wi = Slider(screen, 140, 20, 50, 10, min=0, max=2, step=0.1, initial=wi) output_wi = TextBox(screen, 105, 10, 25, 25, fontSize=15) output_wi.disable() slider_ra = Slider(screen, 250, 20, 50, 10, min=0, max=10, step=0.5, initial=ra) output_ra = TextBox(screen, 215, 10, 25, 25, fontSize=15) output_ra.disable() slider_ri = Slider(screen, 360, 20, 50, 10, min=0, max=10, step=0.5, initial=ri) output_ri = TextBox(screen, 325, 10, 25, 25, fontSize=15) output_ri.disable() running = True time_delay = 100 timer_event = pygame.USEREVENT + 1 pygame.time.set_timer(timer_event, time_delay ) while running: events = pygame.event.get() for event in events: if event.type == QUIT: running = False if event.type == KEYDOWN: if event.key == K_RIGHT: model.update() if event.type == timer_event: model.update() # 实时同步滑块值到模型 wa = slider_wa.getValue() wi = slider_wi.getValue() ra = slider_ra.getValue() ri = slider_ri.getValue() model.wa = wa model.wi = wi model.ra = ra model.ri = ri # 更新文本框显示 output_wa.setText(f"{wa:.1f}") output_wi.setText(f"{wi:.1f}") output_ra.setText(f"{ra:.1f}") output_ri.setText(f"{ri:.1f}") # 完整渲染流程 screen.fill((128, 128, 128)) model.drawGrid(screen, w_width, w_height) pygame_widgets.update(events) # 传递所有事件给widgets pygame.display.update() pygame.quit()
关键修复点
- 事件处理:将
pygame_widgets.update()移至主循环内,传入所有事件确保滑块接收鼠标输入。 - 窗口统一:删除重复的窗口创建代码,仅保留一个
screen窗口。 - 实时同步:在主循环内每次读取滑块最新值,并同步到
model的属性中,让模拟实时响应参数变化。 - 渲染逻辑:将界面填充、文本更新、屏幕刷新等操作移至主循环内,确保每次循环都刷新界面。
内容的提问来源于stack exchange,提问作者Mehmet Akif
相关产品推荐
相关产品推荐

