在pygame中使用pgu制作弹窗

4 投票
2 回答
9328 浏览
提问于 2025-04-16 01:39

我正在用pygame写一个游戏,想要添加一些图形界面元素,比如对话框和按钮。我找了一下,发现了一个不错的图形界面工具包,叫做 pgu。不过,我现在遇到的问题是,虽然对话框能弹出来,但它关不掉。

下面是我代码的简化版本,主要展示我关心的行为:


import pygame, sys
from pgu import gui

screen = None
WIDTH = 640
HEIGHT = 480

def init_pygame():
    global screen
    pygame.display.init()
    screen = pygame.display.set_mode((WIDTH, HEIGHT), pygame.DOUBLEBUF)
    pygame.display.set_caption('Testing PGU')

class SimpleDialog(gui.Dialog):
    def __init__(self):
        title = gui.Label("Spam")
        main = gui.Container(width=20, height=20)
        # I patched PGU to use new style classes.
        super(SimpleDialog, self).__init__(title, main, width=40, height=40)

    def close(self, *args, **kwargs):
        print "closing"
        return super(SimpleDialog, self).close(*args, **kwargs)

def run():
    init_pygame()
    app = gui.App()

    dialog = SimpleDialog()
    app.init(dialog)

    app.paint(screen)
    pygame.display.flip()
    while True:
        app.paint(screen)
        pygame.display.flip()
        for event in pygame.event.get():
            if event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 3: # right mouse button
                    print "opening"
                    dialog.open()
                else:
                    app.event(event)
            elif event.type == pygame.QUIT:
                sys.exit()
            else:
                app.event(event)

if __name__=='__main__':
    run()

我看到的情况是:一个窗口打开了,里面是对话框的全屏版本。但是无论我怎么操作都关不掉它。右键点击会在控制台打印“opening”,而左键点击那个小红圈则会打印“closing”。看起来这个对话框占用了整个背景,而不是只占用一个小区域。

我希望看到的情况是:出现一个大黑屏(我稍后会在上面画东西),然后当我右键点击时,会弹出一个小窗口。当我左键点击关闭按钮时,这个窗口就会消失。

我怀疑这可能和我没有使用桌面环境有关,但我不想让整个游戏都在一个图形界面里。

为了更明确地说,我的问题是:我该如何修改我的代码,从我现在看到的行为变成我想要的行为?如果有人知道比pgu更新的图形界面库,我也愿意尝试。

2 个回答

0

我尝试过类似nmicahaels的回答,想在我的pygame应用中实现一个独立的对话框,但总是遇到一个类型错误:

pygame_pgu-0.21-py3.6.egg\pgu\gui\surface.py", 第10行,在subsurface中 r = pygame.Rect(r) 类型错误:参数必须是矩形样式的对象

(r传入的是None)

去掉对话框的height参数后,这个问题就解决了。以下是调整后的代码:

import pygame, sys
from pgu import gui

# original author: user nmicahaels https://stackoverflow.com/questions/3302973/making-popup-windows-in-pygame-with-pgu

WIDTH = 640
HEIGHT = 480


def init_pygame():
    pygame.display.init()
    screen = pygame.display.set_mode((WIDTH, HEIGHT), pygame.DOUBLEBUF)
    pygame.display.set_caption('Testing PGU')
    return screen


class SimpleDialog(gui.Dialog):
    def __init__(self):
        title = gui.Label("Spam")
        main = gui.Container(width=20, height=20)
        # passing the 'height' parameter resulting in a typerror when paint was called
        super(SimpleDialog, self).__init__(title, main, width=40)  # , height=40)

    def close(self, *args, **kwargs):
        return super(SimpleDialog, self).close(*args, **kwargs)


def run():
    black = (0, 0, 0)
    screen = init_pygame()  # type: pygame.Surface
    refresh = pygame.display.update
    app = gui.App()

    dialog = SimpleDialog()
    # app.init(dialog)

    empty = gui.Container(width=WIDTH, height=HEIGHT)
    app.init(empty)

    app.paint(screen)
    pygame.display.flip()
    while True:
        screen.fill(black)
        app.paint(screen)
        pygame.display.flip()
        for event in pygame.event.get():
            if event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 3:  # right mouse button
                    dialog.open()
                else:
                    app.event(event)
            elif event.type == pygame.QUIT:
                sys.exit()
            else:
                app.event(event)
    refresh()


if __name__ == '__main__':
    run()
3

如果以后有人想这样做,我找到了一种可行的方法:先创建一个空的容器,然后在这个容器上调用 app.init()

empty = gui.Container(width=WIDTH, height=HEIGHT)
gui.init(empty)

撰写回答