Created
June 19, 2018 21:30
-
-
Save Skycocoo/1137bafdaf8c1f4d2303a6292b19532d to your computer and use it in GitHub Desktop.
Pygame embedded in wxPython; deprecated methods removed
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
### PYGAME IN WX ### | |
# A simple test of embedding Pygame in a wxPython frame | |
# | |
# By David Barker (aka Animatinator), 14/07/2010 | |
# Patch for cross-platform support by Sean McKean, 16/07/2010 | |
# Patch to fix redrawing issue by David Barker, 20/07/2010 | |
# Second window demo added by David Barker, 21/07/2010 | |
# modified by Yuxi Luo (Skycocoo), 19/06/2018 | |
# removed all deprecated methods to current pygame & wx version | |
# pygame == 1.9.3 | |
# wxpython == 4.0.1 | |
import wx, sys, os, pygame | |
class PygameDisplay(wx.Window): | |
def __init__(self, parent, ID): | |
wx.Window.__init__(self, parent, ID) | |
self.parent = parent | |
self.hwnd = self.GetHandle() | |
self.size = self.GetSize() | |
self.size_dirty = True | |
self.timer = wx.Timer(self) | |
self.Bind(wx.EVT_PAINT, self.OnPaint) | |
self.Bind(wx.EVT_TIMER, self.Update, self.timer) | |
self.Bind(wx.EVT_SIZE, self.OnSize) | |
self.fps = 60.0 | |
self.timespacing = 1000.0 / self.fps | |
self.timer.Start(self.timespacing, False) | |
self.linespacing = 5 | |
def Update(self, event): | |
# Any update tasks would go here (moving sprites, advancing animation frames etc.) | |
self.Redraw() | |
def Redraw(self): | |
if self.size_dirty: | |
self.screen = pygame.Surface(self.size, 0, 32) | |
self.size_dirty = False | |
self.screen.fill((0,0,0)) | |
cur = 0 | |
w, h = self.screen.get_size() | |
while cur <= h: | |
pygame.draw.aaline(self.screen, (255, 255, 255), (0, h - cur), (cur, 0)) | |
cur += self.linespacing | |
s = pygame.image.tostring(self.screen, 'RGB') # Convert the surface to an RGB string | |
img = wx.Image(self.size[0], self.size[1], s) # Load this string into a wx image | |
bmp = wx.Bitmap(img) # Get the image in bitmap form | |
dc = wx.ClientDC(self) # Device context for drawing the bitmap | |
dc.DrawBitmap(bmp, 0, 0, False) # Blit the bitmap image to the display | |
del dc | |
def OnPaint(self, event): | |
self.Redraw() | |
event.Skip() # Make sure the parent frame gets told to redraw as well | |
def OnSize(self, event): | |
self.size = self.GetSize() | |
self.size_dirty = True | |
def Kill(self, event): | |
# Make sure Pygame can't be asked to redraw /before/ quitting by unbinding all methods which | |
# call the Redraw() method | |
# (Otherwise wx seems to call Draw between quitting Pygame and destroying the frame) | |
# This may or may not be necessary now that Pygame is just drawing to surfaces | |
self.Unbind(event = wx.EVT_PAINT, handler = self.OnPaint) | |
self.Unbind(event = wx.EVT_TIMER, handler = self.Update, source = self.timer) | |
class FoolDisplay(PygameDisplay): | |
def __init__(self, parent, id): | |
PygameDisplay.__init__(self, parent, id) | |
pygame.font.init() | |
self.mainfont = pygame.font.Font(None, 40) | |
self.text = self.mainfont.render("FOOOOOOL! NOW WE ARE ALL DAMNED!", True, (255, 0, 0)) | |
self.borw = True # True = draw a black background, False = draw a white background | |
self.points = [] # A list of points to draw | |
self.Bind(wx.EVT_LEFT_DOWN, self.OnClick) | |
def Update(self, event): | |
PygameDisplay.Update(self, event) | |
self.borw = not self.borw # Alternate the background colour | |
for i, point in enumerate(self.points): # Slide all the points down and slightly to the right | |
self.points[i] = (point[0] + 0.1, point[1] + 1) | |
def Redraw(self): | |
# If the size has changed, create a new surface to match it | |
if self.size_dirty: | |
self.screen = pygame.Surface(self.size, 0, 32) | |
self.size_dirty = False | |
# Draw the background | |
if self.borw: | |
self.screen.fill((0, 0, 0)) | |
else: | |
self.screen.fill((255, 255, 255)) | |
self.screen.blit(self.text, (0, 0)) | |
# Draw circles at all the stored points | |
for point in self.points: | |
pygame.draw.circle(self.screen, (0, 255, 0), (int(point[0]), int(point[1])), 5) | |
s = pygame.image.tostring(self.screen, 'RGB') # Convert the surface to an RGB string | |
img = wx.Image(self.size[0], self.size[1], s) # Load this string into a wx image | |
bmp = wx.Bitmap(img) # Get the image in bitmap form | |
dc = wx.ClientDC(self) # Device context for drawing the bitmap | |
dc.DrawBitmap(bmp, 0, 0, False) # Blit the bitmap image to the display | |
del dc | |
def OnClick(self, event): | |
self.points.append(event.GetPositionTuple()) # Add a new point at the mouse position | |
class FoolFrame(wx.Frame): | |
def __init__(self, parent): | |
wx.Frame.__init__(self, parent, -1, size = (600, 300), style = wx.CAPTION | wx.SYSTEM_MENU | wx.CLOSE_BOX) | |
self.display = FoolDisplay(self, -1) | |
self.SetTitle("NOOOOOOOO!") | |
class Frame(wx.Frame): | |
def __init__(self, parent): | |
wx.Frame.__init__(self, parent, -1, size = (600, 600)) | |
self.display = PygameDisplay(self, -1) | |
self.statusbar = self.CreateStatusBar() | |
self.statusbar.SetFieldsCount(3) | |
self.statusbar.SetStatusWidths([-3, -4, -2]) | |
self.statusbar.SetStatusText("wxPython", 0) | |
self.statusbar.SetStatusText("Look, it's a nifty status bar!!!", 1) | |
self.Bind(wx.EVT_SIZE, self.OnSize) | |
self.Bind(wx.EVT_CLOSE, self.Kill) | |
self.curframe = 0 | |
self.SetTitle("Pygame embedded in wxPython") | |
self.slider = wx.Slider(self, wx.ID_ANY, 5, 1, 10, style = wx.SL_HORIZONTAL | wx.SL_LABELS) | |
self.slider.SetTickFreq(0.1) | |
self.button = wx.Button(self, -1, "DO NOT PRESS THIS BUTTON") | |
self.timer = wx.Timer(self) | |
self.Bind(wx.EVT_SCROLL, self.OnScroll) | |
self.Bind(wx.EVT_SIZE, self.OnSize) | |
self.Bind(wx.EVT_TIMER, self.Update, self.timer) | |
self.Bind(wx.EVT_BUTTON, self.ButtonClick, self.button) | |
self.timer.Start((1000.0 / self.display.fps)) | |
self.sizer = wx.BoxSizer(wx.VERTICAL) | |
self.sizer2 = wx.BoxSizer(wx.HORIZONTAL) | |
self.sizer2.Add(self.slider, 1, flag = wx.EXPAND | wx.RIGHT, border = 5) | |
self.sizer2.Add(self.button, 0, flag = wx.EXPAND | wx.ALL, border = 5) | |
self.sizer.Add(self.sizer2, 0, flag = wx.EXPAND) | |
self.sizer.Add(self.display, 1, flag = wx.EXPAND) | |
self.SetAutoLayout(True) | |
self.SetSizer(self.sizer) | |
self.Layout() | |
def Kill(self, event): | |
self.display.Kill(event) | |
self.Destroy() | |
def OnSize(self, event): | |
self.Layout() | |
def Update(self, event): | |
self.curframe += 1 | |
self.statusbar.SetStatusText("Frame %i" % self.curframe, 2) | |
def OnScroll(self, event): | |
self.display.linespacing = self.slider.GetValue() | |
def ButtonClick(self, event): | |
# (Commented code replaces the main display with the 'foooool!' display) | |
#self.sizer.Detach(self.display) | |
#self.display.Destroy() | |
#self.display = FoolDisplay(self, -1) | |
#self.sizer.Add(self.display, 1, flag = wx.EXPAND) | |
#self.Layout() | |
newframe = FoolFrame(self) | |
newframe.Show() | |
self.button.SetLabel("YOU WERE WARNED!") | |
self.Layout() | |
class App(wx.App): | |
def OnInit(self): | |
self.frame = Frame(parent = None) | |
self.frame.Show() | |
self.SetTopWindow(self.frame) | |
return True | |
if __name__ == "__main__": | |
app = App() | |
app.MainLoop() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I know this is old, but this is still interesting. Is there a way to get pygame events using this?