I'm trying to add some gui elements (dialog boxes with buttons) to a game I'm writing with pygame. I looked around for a decent gui toolkit and ended up with pgu. Anyway, I'm trying to get it to pop up a dialog box, which it does (sort of), but it isn't closing.
Here's a simplified version of my code that just shows the behavior I care about:
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()
The behavior I'm seeing: A window opens with a full screen version of the dialog box. Nothing I do will close it, though right clicking will print "opening" on my console and left clicking the little red circle will get it to print "closing". It looks like the dialog box is using the whole background surface instead of a smaller one just for itself.
The behavior I'd like to see: A big black screen appears (I'll draw on it later) and when I right click o开发者_StackOverflow中文版n it, a little window opens up. When I left click the close button, the window goes away.
I suspect it has something to do with the fact that I'm not using a Desktop, but I don't want the whole game to live inside a gui.
Now, just to be explicit, the question: How do I modify my code to get from the behavior I'm seeing to the behavior I'd like to see? I'm open to using a different gui library if someone knows of something more recently maintained than pgu.
In case anyone else ever wants to do this, I found something that works: Create an empty container and call app.init()
on it.
empty = gui.Container(width=WIDTH, height=HEIGHT)
gui.init(empty)
I had tried something similar to nmicahaels's answer to achieve a stand-alone dialog in my pygame app, but I kept getting a typeerror:
pygame_pgu-0.21-py3.6.egg\pgu\gui\surface.py", line 10, in subsurface r = pygame.Rect(r) TypeError: Argument must be rect style object
(r
was being passed a None
)
Removing the dialog height
parameter fixed the issue for me. Here's the adapted code
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()
精彩评论