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

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()

问题根源

  1. 事件处理错误:pygame_widgets.update(event)放在主循环外,滑块无法接收鼠标事件;且主循环内未将事件传递给widgets处理。
  2. 重复创建窗口:先后创建screen和win两个窗口,导致渲染混乱。
  3. 变量更新缺失:滑块值仅在初始化时读取一次,运行中滑块变动后未同步到模型变量。
  4. 渲染逻辑位置错误:界面填充、文本更新、屏幕刷新等代码都在主循环外,永远不会执行。

修复后的代码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 15:40:01