【问题标题】:Issue with updating display in Pygame在 Pygame 中更新显示的问题
【发布时间】:2026-02-11 06:20:07
【问题描述】:

我正在开发一个程序,它允许用户创建和编辑用 Pygame 制作的 GUI。该程序本身将有一个很好的 GUI,为此我正在制作一个模块来简化它的创建。虽然目前其他一切都按我的预期工作,但我正在解决一个我根本无法解决、也无法理解的问题:

当我启动程序时,会出现一个黑色窗口。问题是窗口应该是白色的,并且包含一个带有图像的黑色矩形。我尝试点击它并移动它,但它没有显示任何内容。

起初我以为我没有更新窗口,但我检查了脚本并发现我更新了。然后我开始尝试对窗口进行不同的操作,发现只有退出我的实际屏幕(监视器)的窗口部分得到更新,并且在我将其拖出并放回屏幕的那一刻立即更新。

谁能解释一下发生了什么,为什么会发生,我该如何解决?

编辑

我发现如果我最小化它然后最大化它,窗口也会正确更新。所以问题不是那么严重,但很烦人。

代码如下:

import pygame
import time

def initialize():
    global display
    global screen
    pygame.init()
    display = pygame.display
    screen = None

class Screen():
    def __init__(self, size, color=[255, 255, 255]):
        global screen
        self.size = size
        self.color = color
        self.screen = display.set_mode(self.size)
        self.fill(self.color)
        self.update()
        screen = self
    def update(self, rectangle=None):
        display.update(rectangle)
    def fill(self, color, rectangle=None):
        self.screen.fill(color, rectangle)
    def draw(self, sprite):
        self.screen.blit(sprite.image, sprite.rectangle[0])

class Engine():
    def __init__(self):
        self.events = []
        self.running = False
    def update_events(self):
        self.events += pygame.event.get()
    def get_events(self):
        events = self.events
        self.events = []
        return events
    def start(self, function=None, args=[], kwargs={}, frequency=21, function_first=False):
        self.running = True
        while self.running:
            if function_first and function:
                function(*args, **kwargs)
            self.update_events()
            if not function:
                for event in self.events:
                    if event.type == pygame.QUIT:
                        self.running = False
                        pygame.quit()
                        break
            if not function_first and function:
                function(*args, **kwargs)
            if self.running:
                tick = 1.0 / frequency
                time.sleep(tick)
    def stop(self):
        self.running = False

class Sprite():
    def __init__(self, rectangle, color=[0, 0, 0]):
        self.rectangle = rectangle
        self.color = color
        self.image = None
    def update(self):
        global screen
        screen.fill(self.color, self.rectangle)
        screen.draw(self)
    def load_image(self, image):
        self.image = pygame.image.load(image).convert()

if __name__ == "__main__":
    initialize()
    s = Screen([500, 500])
    e = Engine()
    sprite = Sprite([[10, 10], [200, 200]])
    sprite.load_image("test.png")
    sprite.update()
    s.update()
    e.start()

以下是截图:

当我启动程序时:

当我将窗口拉出屏幕时:

当我把它拉回来时:

【问题讨论】:

    标签: python user-interface pygame


    【解决方案1】:

    您的代码中有一些错误。

    1. 您不会在主循环中更新屏幕。

    2. 您应该始终在主循环的每次迭代中调用 pygame.event.get。

    3. 不要使用 time.sleep,使用 pygame.time.clock.tick

    【讨论】:

    • 你是对的。我不更新循环中的显示,但我在它之前更新它。根据我的经验,我知道这也应该有效。至于调用 pygame.event.get(),我愿意。如果您查看我的代码,您会看到我调用 engine.start() 来启动循环。在其中,我在它的每次迭代中调用 self.update_events() 。尽管如此,我得到的行为是一种我以前从未有过的行为。
    • 不,如果您想在窗口周围拖动,则必须在每次迭代中更新屏幕。没办法
    • 我可以拖动它。但图像不会显示。它总是如此。无论是不断更新屏幕还是只更新一次。
    • @Cosinux,Fred 是对的,如果窗口不是桌面区域内的静止图片,您需要在每一帧都将内容绘制到屏幕上。除此之外,这是我见过的最奇怪的 pygame 实现 :)