wxPython Merge #2 of 2.4 branch --> HEAD (branch tag: wxPy_2_4_merge_2)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@21593 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robin Dunn
2003-07-02 23:13:10 +00:00
parent e234d4c9b7
commit 1fded56b37
535 changed files with 48899 additions and 20067 deletions

View File

@@ -6,11 +6,11 @@ can do simple drawings upon.
"""
from wxPython.wx import *
import wx # This module uses the new wx namespace
#----------------------------------------------------------------------
class DoodleWindow(wxWindow):
class DoodleWindow(wx.Window):
menuColours = { 100 : 'Black',
101 : 'Yellow',
102 : 'Red',
@@ -32,7 +32,7 @@ class DoodleWindow(wxWindow):
def __init__(self, parent, ID):
wxWindow.__init__(self, parent, ID, style=wxNO_FULL_REPAINT_ON_RESIZE)
wx.Window.__init__(self, parent, ID, style=wx.NO_FULL_REPAINT_ON_RESIZE)
self.SetBackgroundColour("WHITE")
self.listeners = []
self.thickness = 1
@@ -44,20 +44,20 @@ class DoodleWindow(wxWindow):
self.InitBuffer()
# hook some mouse events
EVT_LEFT_DOWN(self, self.OnLeftDown)
EVT_LEFT_UP(self, self.OnLeftUp)
EVT_RIGHT_UP(self, self.OnRightUp)
EVT_MOTION(self, self.OnMotion)
wx.EVT_LEFT_DOWN(self, self.OnLeftDown)
wx.EVT_LEFT_UP(self, self.OnLeftUp)
wx.EVT_RIGHT_UP(self, self.OnRightUp)
wx.EVT_MOTION(self, self.OnMotion)
# the window resize event and idle events for managing the buffer
EVT_SIZE(self, self.OnSize)
EVT_IDLE(self, self.OnIdle)
wx.EVT_SIZE(self, self.OnSize)
wx.EVT_IDLE(self, self.OnIdle)
# and the refresh event
EVT_PAINT(self, self.OnPaint)
wx.EVT_PAINT(self, self.OnPaint)
# When the window is destroyed, clean up resources.
EVT_WINDOW_DESTROY(self, self.Cleanup)
wx.EVT_WINDOW_DESTROY(self, self.Cleanup)
def Cleanup(self, evt):
@@ -69,9 +69,9 @@ class DoodleWindow(wxWindow):
def InitBuffer(self):
"""Initialize the bitmap used for buffering the display."""
size = self.GetClientSize()
self.buffer = wxEmptyBitmap(size.width, size.height)
dc = wxBufferedDC(None, self.buffer)
dc.SetBackground(wxBrush(self.GetBackgroundColour()))
self.buffer = wx.EmptyBitmap(size.width, size.height)
dc = wx.BufferedDC(None, self.buffer)
dc.SetBackground(wx.Brush(self.GetBackgroundColour()))
dc.Clear()
self.DrawLines(dc)
self.reInitBuffer = False
@@ -80,14 +80,14 @@ class DoodleWindow(wxWindow):
def SetColour(self, colour):
"""Set a new colour and make a matching pen"""
self.colour = colour
self.pen = wxPen(wxNamedColour(self.colour), self.thickness, wxSOLID)
self.pen = wx.Pen(self.colour, self.thickness, wx.SOLID)
self.Notify()
def SetThickness(self, num):
"""Set a new line thickness and make a matching pen"""
self.thickness = num
self.pen = wxPen(wxNamedColour(self.colour), self.thickness, wxSOLID)
self.pen = wx.Pen(self.colour, self.thickness, wx.SOLID)
self.Notify()
@@ -103,20 +103,20 @@ class DoodleWindow(wxWindow):
def MakeMenu(self):
"""Make a menu that can be popped up later"""
menu = wxMenu()
menu = wx.Menu()
keys = self.menuColours.keys()
keys.sort()
for k in keys:
text = self.menuColours[k]
menu.Append(k, text, kind=wxITEM_CHECK)
EVT_MENU_RANGE(self, 100, 200, self.OnMenuSetColour)
EVT_UPDATE_UI_RANGE(self, 100, 200, self.OnCheckMenuColours)
menu.Append(k, text, kind=wx.ITEM_CHECK)
wx.EVT_MENU_RANGE(self, 100, 200, self.OnMenuSetColour)
wx.EVT_UPDATE_UI_RANGE(self, 100, 200, self.OnCheckMenuColours)
menu.Break()
for x in range(1, self.maxThickness+1):
menu.Append(x, str(x), kind=wxITEM_CHECK)
EVT_MENU_RANGE(self, 1, self.maxThickness, self.OnMenuSetThickness)
EVT_UPDATE_UI_RANGE(self, 1, self.maxThickness, self.OnCheckMenuThickness)
menu.Append(x, str(x), kind=wx.ITEM_CHECK)
wx.EVT_MENU_RANGE(self, 1, self.maxThickness, self.OnMenuSetThickness)
wx.EVT_UPDATE_UI_RANGE(self, 1, self.maxThickness, self.OnCheckMenuThickness)
self.menu = menu
@@ -126,8 +126,11 @@ class DoodleWindow(wxWindow):
text = self.menuColours[event.GetId()]
if text == self.colour:
event.Check(True)
event.SetText(text.upper())
else:
event.Check(False)
event.SetText(text)
def OnCheckMenuThickness(self, event):
if event.GetId() == self.thickness:
event.Check(True)
@@ -164,7 +167,7 @@ class DoodleWindow(wxWindow):
current one. Save the coordinants for redraws.
"""
if event.Dragging() and event.LeftIsDown():
dc = wxBufferedDC(wxClientDC(self), self.buffer)
dc = wx.BufferedDC(wx.ClientDC(self), self.buffer)
dc.BeginDrawing()
dc.SetPen(self.pen)
pos = event.GetPositionTuple()
@@ -200,10 +203,10 @@ class DoodleWindow(wxWindow):
Called when the window is exposed.
"""
# Create a buffered paint DC. It will create the real
# wxPaintDC and then blit the bitmap to it when dc is
# wx.PaintDC and then blit the bitmap to it when dc is
# deleted. Since we don't need to draw anything else
# here that's all there is to it.
dc = wxBufferedPaintDC(self, self.buffer)
dc = wx.BufferedPaintDC(self, self.buffer)
def DrawLines(self, dc):
@@ -212,7 +215,7 @@ class DoodleWindow(wxWindow):
"""
dc.BeginDrawing()
for colour, thickness, line in self.lines:
pen = wxPen(wxNamedColour(colour), thickness, wxSOLID)
pen = wx.Pen(colour, thickness, wx.SOLID)
dc.SetPen(pen)
for coords in line:
apply(dc.DrawLine, coords)
@@ -240,16 +243,16 @@ class DoodleWindow(wxWindow):
#----------------------------------------------------------------------
class DoodleFrame(wxFrame):
class DoodleFrame(wx.Frame):
def __init__(self, parent):
wxFrame.__init__(self, parent, -1, "Doodle Frame", size=(800,600),
style=wxDEFAULT_FRAME_STYLE | wxNO_FULL_REPAINT_ON_RESIZE)
wx.Frame.__init__(self, parent, -1, "Doodle Frame", size=(800,600),
style=wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE)
doodle = DoodleWindow(self, -1)
#----------------------------------------------------------------------
if __name__ == '__main__':
app = wxPySimpleApp()
app = wx.PySimpleApp()
frame = DoodleFrame(None)
frame.Show(True)
app.MainLoop()

View File

@@ -4008,4 +4008,261 @@ I472
I599
I473
tatp56
a(S'Red'
p57
I4
(lp58
(I503
I412
I503
I411
ta(I503
I411
I504
I411
ta(I504
I411
I504
I410
ta(I504
I410
I505
I410
ta(I505
I410
I505
I409
ta(I505
I409
I506
I409
ta(I506
I409
I507
I409
ta(I507
I409
I507
I408
ta(I507
I408
I508
I408
ta(I508
I408
I509
I408
ta(I509
I408
I510
I408
ta(I510
I408
I511
I408
ta(I511
I408
I511
I409
ta(I511
I409
I511
I410
ta(I511
I410
I512
I410
ta(I512
I410
I512
I411
ta(I512
I411
I512
I412
ta(I512
I412
I512
I413
ta(I512
I413
I512
I414
ta(I512
I414
I512
I415
ta(I512
I415
I511
I415
ta(I511
I415
I511
I416
ta(I511
I416
I510
I416
ta(I510
I416
I510
I417
ta(I510
I417
I509
I417
ta(I509
I417
I508
I418
ta(I508
I418
I508
I419
ta(I508
I419
I507
I420
ta(I507
I420
I506
I421
ta(I506
I421
I505
I421
ta(I505
I421
I504
I422
ta(I504
I422
I503
I423
ta(I503
I423
I503
I424
ta(I503
I424
I502
I425
ta(I502
I425
I502
I426
tatp59
a(g57
I4
(lp60
(I503
I414
I502
I414
ta(I502
I414
I502
I413
ta(I502
I413
I501
I413
ta(I501
I413
I499
I412
ta(I499
I412
I498
I412
ta(I498
I412
I497
I412
ta(I497
I412
I496
I412
ta(I496
I412
I495
I412
ta(I495
I412
I494
I412
ta(I494
I412
I493
I413
ta(I493
I413
I493
I414
ta(I493
I414
I493
I415
ta(I493
I415
I493
I416
ta(I493
I416
I493
I417
ta(I493
I417
I493
I418
ta(I493
I418
I493
I419
ta(I493
I419
I493
I420
ta(I493
I420
I494
I421
ta(I494
I421
I495
I422
ta(I495
I422
I496
I422
ta(I496
I422
I497
I423
ta(I497
I423
I498
I423
ta(I498
I423
I498
I424
ta(I498
I424
I499
I424
ta(I499
I424
I500
I424
ta(I500
I424
I500
I425
ta(I500
I425
I501
I425
tatp61
a.

View File

@@ -7,10 +7,12 @@ intelligent Frame. This one has a menu and a statusbar, is able to
save and reload doodles, clear the workspace, and has a simple control
panel for setting color and line thickness in addition to the popup
menu that DoodleWindow provides. There is also a nice About dialog
implmented using an wxHtmlWindow.
implmented using an wx.html.HtmlWindow.
"""
from wxPython.wx import *
import wx # This module uses the new wx namespace
import wx.html
from wx.lib import buttons # for generic button classes
from doodle import DoodleWindow
import os, cPickle
@@ -18,25 +20,28 @@ import os, cPickle
#----------------------------------------------------------------------
idNEW = 11001
idOPEN = 11002
idSAVE = 11003
idSAVEAS = 11004
idCLEAR = 11005
idEXIT = 11006
idABOUT = 11007
wx.RegisterId(5000) # Give a high starting value for the IDs, just for kicks
idNEW = wx.NewId()
idOPEN = wx.NewId()
idSAVE = wx.NewId()
idSAVEAS = wx.NewId()
idCLEAR = wx.NewId()
idEXIT = wx.NewId()
idABOUT = wx.NewId()
class DoodleFrame(wxFrame):
class DoodleFrame(wx.Frame):
"""
A DoodleFrame contains a DoodleWindow and a ControlPanel and manages
their layout with a wxBoxSizer. A menu and associated event handlers
their layout with a wx.BoxSizer. A menu and associated event handlers
provides for saving a doodle to a file, etc.
"""
title = "Do a doodle"
def __init__(self, parent):
wxFrame.__init__(self, parent, -1, self.title, size=(800,600),
style=wxDEFAULT_FRAME_STYLE | wxNO_FULL_REPAINT_ON_RESIZE)
wx.Frame.__init__(self, parent, -1, self.title, size=(800,600),
style=wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE)
self.CreateStatusBar()
self.MakeMenu()
self.filename = None
@@ -47,9 +52,9 @@ class DoodleFrame(wxFrame):
# Create a sizer to layout the two windows side-by-side.
# Both will grow vertically, the doodle window will grow
# horizontally as well.
box = wxBoxSizer(wxHORIZONTAL)
box.Add(cPanel, 0, wxEXPAND)
box.Add(self.doodle, 1, wxEXPAND)
box = wx.BoxSizer(wx.HORIZONTAL)
box.Add(cPanel, 0, wx.EXPAND)
box.Add(self.doodle, 1, wx.EXPAND)
# Tell the frame that it should layout itself in response to
# size events.
@@ -73,15 +78,19 @@ class DoodleFrame(wxFrame):
f.close()
self.doodle.SetLinesData(data)
except cPickle.UnpicklingError:
wxMessageBox("%s is not a doodle file." % self.filename,
"oops!", style=wxOK|wxICON_EXCLAMATION)
wx.MessageBox("%s is not a doodle file." % self.filename,
"oops!", style=wx.OK|wx.ICON_EXCLAMATION)
def MakeMenu(self):
# create the file menu
menu1 = wxMenu()
menu1.Append(idOPEN, "&Open", "Open a doodle file")
menu1.Append(idSAVE, "&Save", "Save the doodle")
menu1 = wx.Menu()
# Using the "\tKeyName" syntax automatically creates a
# wx.AcceleratorTable for this frame and binds the keys to
# the menu items.
menu1.Append(idOPEN, "&Open\tCtrl-O", "Open a doodle file")
menu1.Append(idSAVE, "&Save\tCtrl-S", "Save the doodle")
menu1.Append(idSAVEAS, "Save &As", "Save the doodle in a new file")
menu1.AppendSeparator()
menu1.Append(idCLEAR, "&Clear", "Clear the current doodle")
@@ -89,30 +98,30 @@ class DoodleFrame(wxFrame):
menu1.Append(idEXIT, "E&xit", "Terminate the application")
# and the help menu
menu2 = wxMenu()
menu2.Append(idABOUT, "&About", "Display the gratuitous 'about this app' thingamajig")
menu2 = wx.Menu()
menu2.Append(idABOUT, "&About\tCtrl-H", "Display the gratuitous 'about this app' thingamajig")
# and add them to a menubar
menuBar = wxMenuBar()
menuBar = wx.MenuBar()
menuBar.Append(menu1, "&File")
menuBar.Append(menu2, "&Help")
self.SetMenuBar(menuBar)
EVT_MENU(self, idOPEN, self.OnMenuOpen)
EVT_MENU(self, idSAVE, self.OnMenuSave)
EVT_MENU(self, idSAVEAS, self.OnMenuSaveAs)
EVT_MENU(self, idCLEAR, self.OnMenuClear)
EVT_MENU(self, idEXIT, self.OnMenuExit)
EVT_MENU(self, idABOUT, self.OnMenuAbout)
wx.EVT_MENU(self, idOPEN, self.OnMenuOpen)
wx.EVT_MENU(self, idSAVE, self.OnMenuSave)
wx.EVT_MENU(self, idSAVEAS, self.OnMenuSaveAs)
wx.EVT_MENU(self, idCLEAR, self.OnMenuClear)
wx.EVT_MENU(self, idEXIT, self.OnMenuExit)
wx.EVT_MENU(self, idABOUT, self.OnMenuAbout)
wildcard = "Doodle files (*.ddl)|*.ddl|All files (*.*)|*.*"
def OnMenuOpen(self, event):
dlg = wxFileDialog(self, "Open doodle file...", os.getcwd(),
style=wxOPEN, wildcard = self.wildcard)
if dlg.ShowModal() == wxID_OK:
dlg = wx.FileDialog(self, "Open doodle file...", os.getcwd(),
style=wx.OPEN, wildcard = self.wildcard)
if dlg.ShowModal() == wx.ID_OK:
self.filename = dlg.GetPath()
self.ReadFile()
self.SetTitle(self.title + ' -- ' + self.filename)
@@ -127,10 +136,10 @@ class DoodleFrame(wxFrame):
def OnMenuSaveAs(self, event):
dlg = wxFileDialog(self, "Save doodle as...", os.getcwd(),
style=wxSAVE | wxOVERWRITE_PROMPT,
dlg = wx.FileDialog(self, "Save doodle as...", os.getcwd(),
style=wx.SAVE | wx.OVERWRITE_PROMPT,
wildcard = self.wildcard)
if dlg.ShowModal() == wxID_OK:
if dlg.ShowModal() == wx.ID_OK:
filename = dlg.GetPath()
if not os.path.splitext(filename)[1]:
filename = filename + '.ddl'
@@ -159,7 +168,7 @@ class DoodleFrame(wxFrame):
#----------------------------------------------------------------------
class ControlPanel(wxPanel):
class ControlPanel(wx.Panel):
"""
This class implements a very simple control panel for the DoodleWindow.
It creates buttons for each of the colours and thickneses supported by
@@ -167,36 +176,51 @@ class ControlPanel(wxPanel):
also a little window that shows an example doodleLine in the selected
values. Nested sizers are used for layout.
"""
BMP_SIZE = 16
BMP_BORDER = 3
def __init__(self, parent, ID, doodle):
wxPanel.__init__(self, parent, ID, style=wxRAISED_BORDER)
wx.Panel.__init__(self, parent, ID, style=wx.RAISED_BORDER)
numCols = 4
spacing = 4
btnSize = wx.Size(self.BMP_SIZE + 2*self.BMP_BORDER,
self.BMP_SIZE + 2*self.BMP_BORDER)
# Make a grid of buttons for each colour. Attach each button
# event to self.OnSetColour. The button ID is the same as the
# key in the colour dictionary.
self.clrBtns = {}
colours = doodle.menuColours
keys = colours.keys()
keys.sort()
cGrid = wxGridSizer(cols=numCols, hgap=2, vgap=2)
cGrid = wx.GridSizer(cols=numCols, hgap=2, vgap=2)
for k in keys:
bmp = self.MakeBitmap(wxNamedColour(colours[k]))
b = wxBitmapButton(self, k, bmp)
EVT_BUTTON(self, k, self.OnSetColour)
bmp = self.MakeBitmap(colours[k])
b = buttons.GenBitmapToggleButton(self, k, bmp, size=btnSize )
b.SetBezelWidth(1)
b.SetUseFocusIndicator(False)
wx.EVT_BUTTON(self, k, self.OnSetColour)
cGrid.Add(b, 0)
self.clrBtns[colours[k]] = b
self.clrBtns[colours[keys[0]]].SetToggle(True)
# Save the button size so we can use it for the number buttons
btnSize = b.GetSize()
# Make a grid of buttons for the thicknesses. Attach each button
# event to self.OnSetThickness. The button ID is the same as the
# thickness value.
tGrid = wxGridSizer(cols=numCols, hgap=2, vgap=2)
self.thknsBtns = {}
tGrid = wx.GridSizer(cols=numCols, hgap=2, vgap=2)
for x in range(1, doodle.maxThickness+1):
b = wxButton(self, x, str(x), size=btnSize)
EVT_BUTTON(self, x, self.OnSetThickness)
b = buttons.GenToggleButton(self, x, str(x), size=btnSize)
b.SetBezelWidth(1)
b.SetUseFocusIndicator(False)
wx.EVT_BUTTON(self, x, self.OnSetThickness)
tGrid.Add(b, 0)
self.thknsBtns[x] = b
self.thknsBtns[1].SetToggle(True)
# Make a colour indicator window, it is registerd as a listener
# with the doodle window so it will be notified when the settings
@@ -208,10 +232,10 @@ class ControlPanel(wxPanel):
# Make a box sizer and put the two grids and the indicator
# window in it.
box = wxBoxSizer(wxVERTICAL)
box.Add(cGrid, 0, wxALL, spacing)
box.Add(tGrid, 0, wxALL, spacing)
box.Add(ci, 0, wxEXPAND|wxALL, spacing)
box = wx.BoxSizer(wx.VERTICAL)
box.Add(cGrid, 0, wx.ALL, spacing)
box.Add(tGrid, 0, wx.ALL, spacing)
box.Add(ci, 0, wx.EXPAND|wx.ALL, spacing)
self.SetSizer(box)
self.SetAutoLayout(True)
@@ -224,15 +248,15 @@ class ControlPanel(wxPanel):
def MakeBitmap(self, colour):
"""
We can create a bitmap of whatever we want by simply selecting
it into a wxMemoryDC and drawing on it. In this case we just set
it into a wx.MemoryDC and drawing on it. In this case we just set
a background brush and clear the dc.
"""
bmp = wxEmptyBitmap(16,16)
dc = wxMemoryDC()
bmp = wx.EmptyBitmap(self.BMP_SIZE, self.BMP_SIZE)
dc = wx.MemoryDC()
dc.SelectObject(bmp)
dc.SetBackground(wxBrush(colour))
dc.SetBackground(wx.Brush(colour))
dc.Clear()
dc.SelectObject(wxNullBitmap)
dc.SelectObject(wx.NullBitmap)
return bmp
@@ -241,6 +265,10 @@ class ControlPanel(wxPanel):
Use the event ID to get the colour, set that colour in the doodle.
"""
colour = self.doodle.menuColours[event.GetId()]
if colour != self.doodle.colour:
# untoggle the old colour button
self.clrBtns[self.doodle.colour].SetToggle(False)
# set the new colour
self.doodle.SetColour(colour)
@@ -248,22 +276,28 @@ class ControlPanel(wxPanel):
"""
Use the event ID to set the thickness in the doodle.
"""
self.doodle.SetThickness(event.GetId())
thickness = event.GetId()
if thickness != self.doodle.thickness:
# untoggle the old thickness button
self.thknsBtns[self.doodle.thickness].SetToggle(False)
# set the new colour
self.doodle.SetThickness(thickness)
#----------------------------------------------------------------------
class ColourIndicator(wxWindow):
class ColourIndicator(wx.Window):
"""
An instance of this class is used on the ControlPanel to show
a sample of what the current doodle line will look like.
"""
def __init__(self, parent):
wxWindow.__init__(self, parent, -1, style=wxSUNKEN_BORDER)
self.SetBackgroundColour(wxWHITE)
self.SetSize(wxSize(-1, 45))
wx.Window.__init__(self, parent, -1, style=wx.SUNKEN_BORDER)
self.SetBackgroundColour(wx.WHITE)
self.SetSize( (-1, 45) )
self.colour = self.thickness = None
EVT_PAINT(self, self.OnPaint)
wx.EVT_PAINT(self, self.OnPaint)
def Update(self, colour, thickness):
@@ -281,10 +315,10 @@ class ColourIndicator(wxWindow):
This method is called when all or part of the window needs to be
redrawn.
"""
dc = wxPaintDC(self)
dc = wx.PaintDC(self)
if self.colour:
sz = self.GetClientSize()
pen = wxPen(wxNamedColour(self.colour), self.thickness)
pen = wx.Pen(self.colour, self.thickness)
dc.BeginDrawing()
dc.SetPen(pen)
dc.DrawLine(10, sz.height/2, sz.width-10, sz.height/2)
@@ -293,7 +327,7 @@ class ColourIndicator(wxWindow):
#----------------------------------------------------------------------
class DoodleAbout(wxDialog):
class DoodleAbout(wx.Dialog):
""" An about box that uses an HTML window """
text = '''
@@ -318,44 +352,43 @@ instructions: </p>
<p><b>SuperDoodle</b> and <b>wxPython</b> are brought to you by
<b>Robin Dunn</b> and <b>Total Control Software</b>, Copyright
&copy; 1997-2001.</p>
&copy; 1997-2003.</p>
</body>
</html>
'''
def __init__(self, parent):
wxDialog.__init__(self, parent, -1, 'About SuperDoodle',
size=wxSize(420, 380))
from wxPython.html import wxHtmlWindow
wx.Dialog.__init__(self, parent, -1, 'About SuperDoodle',
size=(420, 380) )
html = wxHtmlWindow(self, -1)
html = wx.html.HtmlWindow(self, -1)
html.SetPage(self.text)
button = wxButton(self, wxID_OK, "Okay")
button = wx.Button(self, wx.ID_OK, "Okay")
# constraints for the html window
lc = wxLayoutConstraints()
lc.top.SameAs(self, wxTop, 5)
lc.left.SameAs(self, wxLeft, 5)
lc.bottom.SameAs(button, wxTop, 5)
lc.right.SameAs(self, wxRight, 5)
lc = wx.LayoutConstraints()
lc.top.SameAs(self, wx.Top, 5)
lc.left.SameAs(self, wx.Left, 5)
lc.bottom.SameAs(button, wx.Top, 5)
lc.right.SameAs(self, wx.Right, 5)
html.SetConstraints(lc)
# constraints for the button
lc = wxLayoutConstraints()
lc.bottom.SameAs(self, wxBottom, 5)
lc.centreX.SameAs(self, wxCentreX)
lc = wx.LayoutConstraints()
lc.bottom.SameAs(self, wx.Bottom, 5)
lc.centreX.SameAs(self, wx.CentreX)
lc.width.AsIs()
lc.height.AsIs()
button.SetConstraints(lc)
self.SetAutoLayout(True)
self.Layout()
self.CentreOnParent(wxBOTH)
self.CentreOnParent(wx.BOTH)
#----------------------------------------------------------------------
class DoodleApp(wxApp):
class DoodleApp(wx.App):
def OnInit(self):
frame = DoodleFrame(None)
frame.Show(True)

View File

@@ -0,0 +1,468 @@
"""Hangman.py, a simple wxPython game, inspired by the
old bsd game by Ken Arnold.
From the original man page:
In hangman, the computer picks a word from the on-line
word list and you must try to guess it. The computer
keeps track of which letters have been guessed and how
many wrong guesses you have made on the screen in a
graphic fashion.
That says it all, doesn't it?
Have fun with it,
Harm van der Heijden (H.v.d.Heijden@phys.tue.nl)"""
import random,re
from wxPython.wx import *
class WordFetcher:
builtin_words = ' albatros banana electrometer eggshell'
def __init__(self, filename, min_length = 5):
self.min_length = min_length
print "Trying to open file %s" % (filename,)
try:
f = open(filename, "r")
except:
print "Couldn't open dictionary file %s, using builtins" % (filename,)
self.words = self.builtin_words
self.filename = None
return
self.words = f.read()
self.filename = filename
print "Got %d bytes." % (len(self.words),)
def SetMinLength(min_length):
self.min_length = min_length
def Get(self):
reg = re.compile('\s+([a-zA-Z]+)\s+')
n = 50 # safety valve; maximum number of tries to find a suitable word
while n:
index = int(random.random()*len(self.words))
m = reg.search(self.words[index:])
if m and len(m.groups()[0]) >= self.min_length: break
n = n - 1
if n: return m.groups()[0].lower()
return "error"
def stdprint(x):
print x
class URLWordFetcher(WordFetcher):
def __init__(self, url):
self.OpenURL(url)
WordFetcher.__init__(self, "hangman_dict.txt")
def logprint(self,x):
print x
def RetrieveAsFile(self, host, path=''):
from httplib import HTTP
try:
h = HTTP(host)
except:
self.logprint("Failed to create HTTP connection to %s... is the network available?" % (host))
return None
h.putrequest('GET',path)
h.putheader('Accept','text/html')
h.putheader('Accept','text/plain')
h.endheaders()
errcode, errmsg, headers = h.getreply()
if errcode != 200:
self.logprint("HTTP error code %d: %s" % (errcode, errmsg))
return None
f = h.getfile()
return f
def OpenURL(self,url):
from htmllib import HTMLParser
import formatter
self.url = url
m = re.match('http://([^/]+)(/\S*)\s*', url)
if m:
host = m.groups()[0]
path = m.groups()[1]
else:
m = re.match('http://(\S+)\s*', url)
if not m:
# Invalid URL
self.logprint("Invalid or unsupported URL: %s" % (url))
return
host = m.groups()[0]
path = ''
f = self.RetrieveAsFile(host,path)
if not f:
self.logprint("Could not open %s" % (url))
return
self.logprint("Receiving data...")
data = f.read()
tmp = open('hangman_dict.txt','w')
fmt = formatter.AbstractFormatter(formatter.DumbWriter(tmp))
p = HTMLParser(fmt)
self.logprint("Parsing data...")
p.feed(data)
p.close()
tmp.close()
class HangmanWnd(wxWindow):
def __init__(self, parent, id, pos=wxDefaultPosition, size=wxDefaultSize):
wxWindow.__init__(self, parent, id, pos, size)
self.SetBackgroundColour(wxNamedColour('white'))
if wxPlatform == '__WXGTK__':
self.font = wxFont(12, wxMODERN, wxNORMAL, wxNORMAL)
else:
self.font = wxFont(10, wxMODERN, wxNORMAL, wxNORMAL)
self.SetFocus()
EVT_PAINT(self, self.OnPaint)
def StartGame(self, word):
self.word = word
self.guess = []
self.tries = 0
self.misses = 0
self.Draw()
def EndGame(self):
self.misses = 7;
self.guess = map(chr, range(ord('a'),ord('z')+1))
self.Draw()
def HandleKey(self, key):
self.message = ""
if self.guess.count(key):
self.message = 'Already guessed %s' % (key,)
return 0
self.guess.append(key)
self.guess.sort()
self.tries = self.tries+1
if not key in self.word:
self.misses = self.misses+1
if self.misses == 7:
self.EndGame()
return 1
has_won = 1
for letter in self.word:
if not self.guess.count(letter):
has_won = 0
break
if has_won:
self.Draw()
return 2
self.Draw()
return 0
def Draw(self, dc = None):
if not dc:
dc = wxClientDC(self)
dc.SetFont(self.font)
dc.Clear()
(x,y) = self.GetSizeTuple()
x1 = x-200; y1 = 20
for letter in self.word:
if self.guess.count(letter):
dc.DrawText(letter, x1, y1)
else:
dc.DrawText('.', x1, y1)
x1 = x1 + 10
x1 = x-200
dc.DrawText("tries %d misses %d" % (self.tries,self.misses),x1,50)
guesses = ""
for letter in self.guess:
guesses = guesses + letter
dc.DrawText("guessed:", x1, 70)
dc.DrawText(guesses[:13], x1+80, 70)
dc.DrawText(guesses[13:], x1+80, 90)
dc.SetUserScale(x/1000.0, y/1000.0)
self.DrawVictim(dc)
def DrawVictim(self, dc):
dc.SetPen(wxPen(wxNamedColour('black'), 20))
dc.DrawLines([(10, 980), (10,900), (700,900), (700,940), (720,940),
(720,980), (900,980)])
dc.DrawLines([(100,900), (100, 100), (300,100)])
dc.DrawLine(100,200,200,100)
if ( self.misses == 0 ): return
dc.SetPen(wxPen(wxNamedColour('blue'), 10))
dc.DrawLine(300,100,300,200)
if ( self.misses == 1 ): return
dc.DrawEllipse(250,200,100,100)
if ( self.misses == 2 ): return
dc.DrawLine(300,300,300,600)
if ( self.misses == 3) : return
dc.DrawLine(300,300,250,550)
if ( self.misses == 4) : return
dc.DrawLine(300,300,350,550)
if ( self.misses == 5) : return
dc.DrawLine(300,600,350,850)
if ( self.misses == 6) : return
dc.DrawLine(300,600,250,850)
def OnPaint(self, event):
dc = wxPaintDC(self)
self.Draw(dc)
class HangmanDemo(HangmanWnd):
def __init__(self, wf, parent, id, pos, size):
HangmanWnd.__init__(self, parent, id, pos, size)
self.StartGame("dummy")
self.start_new = 1
self.wf = wf
self.delay = 500
self.timer = self.PlayTimer(self.MakeMove)
def MakeMove(self):
self.timer.Stop()
if self.start_new:
self.StartGame(self.wf.Get())
self.start_new = 0
self.left = list('aaaabcdeeeeefghiiiiijklmnnnoooopqrssssttttuuuuvwxyz')
else:
key = self.left[int(random.random()*len(self.left))]
while self.left.count(key): self.left.remove(key)
self.start_new = self.HandleKey(key)
self.timer.Start(self.delay)
def Stop(self):
self.timer.Stop()
class PlayTimer(wxTimer):
def __init__(self,func):
wxTimer.__init__(self)
self.func = func
self.Start(1000)
def Notify(self):
apply(self.func, ())
class HangmanDemoFrame(wxFrame):
def __init__(self, wf, parent, id, pos, size):
wxFrame.__init__(self, parent, id, "Hangman demo", pos, size)
self.demo = HangmanDemo(wf, self, -1, wxDefaultPosition, wxDefaultSize)
EVT_CLOSE(self, self.OnCloseWindow)
def OnCloseWindow(self, event):
self.demo.timer.Stop()
self.Destroy()
class AboutBox(wxDialog):
def __init__(self, parent,wf):
wxDialog.__init__(self, parent, -1, "About Hangman", wxDefaultPosition, wxSize(350,450))
self.wnd = HangmanDemo(wf, self, -1, wxPoint(1,1), wxSize(350,150))
self.static = wxStaticText(self, -1, __doc__, wxPoint(1,160), wxSize(350, 250))
self.button = wxButton(self, 2001, "OK", wxPoint(150,420), wxSize(50,-1))
EVT_BUTTON(self, 2001, self.OnOK)
def OnOK(self, event):
self.wnd.Stop()
self.EndModal(wxID_OK)
class MyFrame(wxFrame):
def __init__(self, parent, wf):
self.wf = wf
wxFrame.__init__(self, parent, -1, "hangman", wxDefaultPosition, wxSize(400,300))
self.wnd = HangmanWnd(self, -1)
menu = wxMenu()
menu.Append(1001, "New")
menu.Append(1002, "End")
menu.AppendSeparator()
menu.Append(1003, "Reset")
menu.Append(1004, "Demo...")
menu.AppendSeparator()
menu.Append(1005, "Exit")
menubar = wxMenuBar()
menubar.Append(menu, "Game")
menu = wxMenu()
#menu.Append(1010, "Internal", "Use internal dictionary", True)
menu.Append(1011, "ASCII File...")
urls = [ 'wxPython home', 'http://wxPython.org/',
'slashdot.org', 'http://slashdot.org/',
'cnn.com', 'http://cnn.com',
'The New York Times', 'http://www.nytimes.com',
'De Volkskrant', 'http://www.volkskrant.nl/frameless/25000006.html',
'Gnu GPL', 'http://www.fsf.org/copyleft/gpl.html',
'Bijbel: Genesis', 'http://www.coas.com/bijbel/gn1.htm']
urlmenu = wxMenu()
for item in range(0,len(urls),2):
urlmenu.Append(1020+item/2, urls[item], urls[item+1])
urlmenu.Append(1080, 'Other...', 'Enter an URL')
menu.AppendMenu(1012, 'URL', urlmenu, 'Use a webpage')
menu.Append(1013, 'Dump', 'Write contents to stdout')
menubar.Append(menu, "Dictionary")
self.urls = urls
self.urloffset = 1020
menu = wxMenu()
menu.Append(1090, "About...")
menubar.Append(menu, "Help")
self.SetMenuBar(menubar)
self.CreateStatusBar(2)
EVT_MENU(self, 1001, self.OnGameNew)
EVT_MENU(self, 1002, self.OnGameEnd)
EVT_MENU(self, 1003, self.OnGameReset)
EVT_MENU(self, 1004, self.OnGameDemo)
EVT_MENU(self, 1005, self.OnWindowClose)
EVT_MENU(self, 1011, self.OnDictFile)
EVT_MENU_RANGE(self, 1020, 1020+len(urls)/2, self.OnDictURL)
EVT_MENU(self, 1080, self.OnDictURLSel)
EVT_MENU(self, 1013, self.OnDictDump)
EVT_MENU(self, 1090, self.OnHelpAbout)
EVT_CHAR(self.wnd, self.OnChar)
self.OnGameReset()
def OnGameNew(self, event):
word = self.wf.Get()
self.in_progress = 1
self.SetStatusText("",0)
self.wnd.StartGame(word)
def OnGameEnd(self, event):
self.UpdateAverages(0)
self.in_progress = 0
self.SetStatusText("",0)
self.wnd.EndGame()
def OnGameReset(self, event=None):
self.played = 0
self.won = 0
self.history = []
self.average = 0.0
self.OnGameNew(None)
def OnGameDemo(self, event):
frame = HangmanDemoFrame(self.wf, self, -1, wxDefaultPosition, self.GetSize())
frame.Show(True)
def OnDictFile(self, event):
fd = wxFileDialog(self)
if (self.wf.filename):
fd.SetFilename(self.wf.filename)
if fd.ShowModal() == wxID_OK:
file = fd.GetPath()
self.wf = WordFetcher(file)
def OnDictURL(self, event):
item = (event.GetId() - self.urloffset)*2
print "Trying to open %s at %s" % (self.urls[item], self.urls[item+1])
self.wf = URLWordFetcher(self.urls[item+1])
def OnDictURLSel(self, event):
msg = wxTextEntryDialog(self, "Enter the URL of the dictionary document", "Enter URL")
if msg.ShowModal() == wxID_OK:
url = msg.GetValue()
self.wf = URLWordFetcher(url)
def OnDictDump(self, event):
print self.wf.words
def OnHelpAbout(self, event):
about = AboutBox(self, self.wf)
about.ShowModal()
about.wnd.Stop() # that damn timer won't stop!
def UpdateAverages(self, has_won):
if has_won:
self.won = self.won + 1
self.played = self.played+1
self.history.append(self.wnd.misses) # ugly
total = 0.0
for m in self.history:
total = total + m
self.average = float(total/len(self.history))
def OnChar(self, event):
if not self.in_progress:
#print "new"
self.OnGameNew(None)
return
key = event.KeyCode();
#print key
if key >= ord('A') and key <= ord('Z'):
key = key + ord('a') - ord('A')
key = chr(key)
if key < 'a' or key > 'z':
event.Skip()
return
res = self.wnd.HandleKey(key)
if res == 0:
self.SetStatusText(self.wnd.message)
elif res == 1:
self.UpdateAverages(0)
self.SetStatusText("Too bad, you're dead!",0)
self.in_progress = 0
elif res == 2:
self.in_progress = 0
self.UpdateAverages(1)
self.SetStatusText("Congratulations!",0)
if self.played:
percent = (100.*self.won)/self.played
else:
percent = 0.0
self.SetStatusText("p %d, w %d (%g %%), av %g" % (self.played,self.won, percent, self.average),1)
def OnWindowClose(self, event):
self.Destroy()
class MyApp(wxApp):
def OnInit(self):
if wxPlatform == '__WXGTK__':
defaultfile = "/usr/share/games/hangman-words"
elif wxPlatform == '__WXMSW__':
defaultfile = "c:\\windows\\hardware.txt"
else:
defaultfile = ""
wf = WordFetcher(defaultfile)
frame = MyFrame(None, wf)
self.SetTopWindow(frame)
frame.Show(True)
return True
if __name__ == '__main__':
app = MyApp(0)
app.MainLoop()
#----------------------------------------------------------------------
overview = __doc__
def runTest(frame, nb, log):
if wxPlatform == '__WXGTK__' or wxPlatform == '__WXMOTIF__':
defaultfile = "/usr/share/games/hangman-words"
elif wxPlatform == '__WXMSW__':
defaultfile = "c:\\windows\\hardware.txt"
else:
defaultfile = ""
wf = WordFetcher(defaultfile)
win = MyFrame(frame, wf)
frame.otherWin = win
win.Show(True)
#----------------------------------------------------------------------

View File

@@ -0,0 +1 @@
# Python package.

View File

@@ -0,0 +1,27 @@
#!/usr/bin/env python
"""Basic application class."""
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
__cvsid__ = "$Id$"
__revision__ = "$Revision$"[11:-2]
import wx
from frame import Frame
class App(wx.App):
"""Application class."""
def OnInit(self):
self.frame = Frame()
self.frame.Show()
self.SetTopWindow(self.frame)
return True
def main():
app = App()
app.MainLoop()
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,33 @@
#!/usr/bin/env python
"""Basic frame class, with App for testing."""
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
__cvsid__ = "$Id$"
__revision__ = "$Revision$"[11:-2]
import wx
class Frame(wx.Frame):
"""Frame class."""
def __init__(self, parent=None, id=-1, title='Title',
pos=wx.DefaultPosition, size=(400, 200)):
"""Create a Frame instance."""
wx.Frame.__init__(self, parent, id, title, pos, size)
class App(wx.App):
"""Application class."""
def OnInit(self):
self.frame = Frame()
self.frame.Show()
self.SetTopWindow(self.frame)
return True
def main():
app = App()
app.MainLoop()
if __name__ == '__main__':
main()

View File

@@ -0,0 +1 @@
# Python package.

View File

@@ -0,0 +1,38 @@
#!/usr/bin/env python
"""Hello, wxPython! program."""
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
__cvsid__ = "$Id$"
__revision__ = "$Revision$"[11:-2]
import wx
class Frame(wx.Frame):
"""Frame class that displays an image."""
def __init__(self, image, parent=None, id=-1,
pos=wx.DefaultPosition, title='Hello, wxPython!'):
"""Create a Frame instance and display image."""
temp = image.ConvertToBitmap()
size = temp.GetWidth(), temp.GetHeight()
wx.Frame.__init__(self, parent, id, title, pos, size)
self.bmp = wx.StaticBitmap(parent=self, id=-1, bitmap=temp)
class App(wx.App):
"""Application class."""
def OnInit(self):
wx.InitAllImageHandlers()
image = wx.Image('wxPython.jpg', wx.BITMAP_TYPE_JPEG)
self.frame = Frame(image)
self.frame.Show()
self.SetTopWindow(self.frame)
return True
def main():
app = App()
app.MainLoop()
if __name__ == '__main__':
main()

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB