wxPython in Action - é误æ示ï¼åçäºå¼å¸¸
wxPython in Action - é误æ示ï¼åçäºå¼å¸¸
wxPython in Action - é误æ示ï¼åçäºå¼å¸¸
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
<strong>wxPython</strong> <strong>in</strong> <strong>Action</strong><br />
——<br />
1 / 565
Part1 <strong>wxPython</strong> 19<br />
1. <strong>wxPython</strong> 19<br />
1.1 <strong>wxPython</strong> 20<br />
1.2 <strong>wxPython</strong> 20<br />
1.2.1 <strong>wxPython</strong> 21<br />
1.2.2 22<br />
<strong>wxPython</strong> application 23<br />
23<br />
23<br />
1.3 <strong>wxPython</strong> 24<br />
1.4 hello.py 26<br />
2<strong>wxPython</strong> 28<br />
2.1 28<br />
2.2 29<br />
2.2.1 wx.App 29<br />
wx.App 30<br />
2.2.2 31<br />
2.3 <strong>wxPython</strong> 31<br />
2.3.1 32<br />
2.3.2 34<br />
2.4 <strong>wxPython</strong> 34<br />
2.4.1 35<br />
2.4.2 35<br />
2.5 36<br />
2.5.1 wx.Frame 36<br />
2 / 565
2.5.2 <strong>wxPython</strong>ID 37<br />
ID 38<br />
NewID() 38<br />
2.5.3 wx.Sizewx.Po<strong>in</strong>t 38<br />
2.5.4 wx.Frame 39<br />
2.6 41<br />
2.6.1 42<br />
2.6.2 44<br />
2.7 45<br />
46<br />
47<br />
47<br />
2.8 48<br />
2.9 49<br />
3 51<br />
3.1 51<br />
3.2 52<br />
3.2.1 54<br />
3.2.2 55<br />
3.2.3 55<br />
3.3 56<br />
3.3.1 wx.EvtHandler 57<br />
3.4 <strong>wxPython</strong> 61<br />
3.4.1 62<br />
64<br />
64<br />
65<br />
3 / 565
66<br />
67<br />
3.4.2 Skip() 68<br />
3.5 70<br />
3.6 71<br />
3.6.1 71<br />
71<br />
3.7 75<br />
4PyCrust<strong>wxPython</strong> 76<br />
4.1 <strong>wxPython</strong> 76<br />
PyCrustPython shell 77<br />
4.2 PyCrust 79<br />
4.2.1 80<br />
4.2.2 80<br />
4.2.3 81<br />
4.2.4 Python 81<br />
4.2.5 82<br />
4.2.6 83<br />
4.2.7 shell 84<br />
4.2.8 85<br />
4.3 PyCrust notebook 87<br />
4.3.1 Namespace 87<br />
4.3.2 Display 89<br />
4.3.3 Calltip 89<br />
4.3.4 Session 90<br />
4.3.5 Dispatcher 90<br />
4.4 PyCrust<strong>wxPython</strong> 92<br />
4 / 565
4.5 Py 96<br />
4.5.1 GUI 97<br />
4.5.2 97<br />
buffer 98<br />
crust 100<br />
dispatcher 100<br />
editor 102<br />
fill<strong>in</strong>g 102<br />
<strong>in</strong>terpreter 103<br />
<strong>in</strong>trospect 103<br />
shell 103<br />
4.6 <strong>wxPython</strong>Py 104<br />
4.7 108<br />
5 109<br />
5.1 109<br />
5.1.1 110<br />
5.1.2 113<br />
5.1.3 114<br />
5.2 (Model)(View) 118<br />
5.2.1 MVC(Model-View-Controller) 118<br />
5.2.2 <strong>wxPython</strong>PyGridTableBase 120<br />
PyGridTableBase 122<br />
PyGridTableBase 123<br />
PyGridTableBase 123<br />
PyGridTableBase 125<br />
PyGridTableBase 127<br />
5.2.3 129<br />
5 / 565
5.3 GUI 133<br />
5.3.1 unittest 134<br />
5.3.2 unittest 135<br />
5.3.3 137<br />
5.4 138<br />
6 140<br />
6.1 141<br />
6.1.1 141<br />
141<br />
147<br />
6.2 149<br />
6.2.1 149<br />
6.2.2 152<br />
6.3 156<br />
6.3.1 156<br />
6.3.2 160<br />
6.4 161<br />
6.4.1 161<br />
sizer 161<br />
sizer 162<br />
6.4.2 (about) 168<br />
6.4.3 170<br />
6.5 172<br />
Part 2 <strong>wxPython</strong> 174<br />
7 175<br />
7.1 175<br />
6 / 565
7.1.1 175<br />
176<br />
178<br />
178<br />
7.1.2 179<br />
179<br />
180<br />
7.1.3 181<br />
7.1.4 182<br />
184<br />
7.1.5 186<br />
7.1.6 187<br />
7.1.7 187<br />
7.1.8 188<br />
7.2 189<br />
7.2.1 189<br />
7.2.2 191<br />
7.2.3 toggle button 192<br />
7.2.4 193<br />
7.3 196<br />
7.3.1 196<br />
197<br />
198<br />
7.3.2 199<br />
199<br />
7.3.3 201<br />
7.4 202<br />
7.4.1 202<br />
7 / 565
7.4.2 radio button 204<br />
205<br />
206<br />
7.4.3 209<br />
209<br />
7.4.4 212<br />
7.4.5 213<br />
7.4.6 214<br />
7.5 216<br />
8 218<br />
8.1 218<br />
8.1.1 218<br />
218<br />
219<br />
8.1.2 221<br />
8.1.3 223<br />
223<br />
224<br />
8.1.4 225<br />
226<br />
227<br />
8.2 227<br />
8.2.1 wx.Frame 227<br />
8.2.2 230<br />
8.2.3 231<br />
232<br />
233<br />
8 / 565
234<br />
8.3 235<br />
8.3.1 MDI 235<br />
8.7 236<br />
8.3.2 238<br />
8.3.3 239<br />
8.3.4 242<br />
8.4 244<br />
8.4.1 245<br />
8.4.2 246<br />
8.4.3 249<br />
8.4.4 250<br />
8.4.5 251<br />
8.5 252<br />
9 253<br />
9.1 253<br />
9.1.1 253<br />
9.1.2 255<br />
wx.MessageDialog 256<br />
wx.MessageBox() 257<br />
9.1.3 258<br />
9.1.4 261<br />
9.1.5 262<br />
9.2 264<br />
9.2.1 264<br />
266<br />
267<br />
9 / 565
9.2.2 269<br />
9.2.3 271<br />
9.2.4 273<br />
9.3 274<br />
9.4 278<br />
9.5 validator 279<br />
9.5.1 279<br />
9.5.2 283<br />
9.5.3 287<br />
9.6 290<br />
10<strong>wxPython</strong> 292<br />
10.1 292<br />
10.1.1 293<br />
10.1.2 293<br />
10.1.3 296<br />
10.1.4 300<br />
10.2 301<br />
10.2.1 301<br />
10.2.2 304<br />
10.2.3 306<br />
308<br />
309<br />
10.2.4 310<br />
10.3 313<br />
10.3.1 313<br />
10.3.2 315<br />
10.3.3 318<br />
10 / 565
10.4 320<br />
10.4.1 321<br />
10.4.2 321<br />
321<br />
321<br />
321<br />
322<br />
322<br />
10.5 323<br />
11 sizer 325<br />
11.1 sizer 325<br />
sizer 326<br />
11.2 sizergrid sizer 327<br />
11.2.1 grid sizer 327<br />
11.2.2 sizer 330<br />
Add() 330<br />
<strong>in</strong>sert() 331<br />
Prepend() 331<br />
11.2.3 sizer 332<br />
11.2.4 sizer 335<br />
11.2.5 sizer 337<br />
11.3 sizer 339<br />
11.3.1 flex grid sizer 339<br />
11.3.2 grid bag sizer 343<br />
grid bag sizerAdd() 345<br />
11.3.3 box sizer 347<br />
11.3.4 static box sizer 351<br />
11 / 565
11.4 sizer 354<br />
11.5 358<br />
12 360<br />
12.1 360<br />
12.1.1 361<br />
363<br />
image 364<br />
bitmap 364<br />
12.1.2 365<br />
367<br />
alpha 367<br />
12.1.3 368<br />
370<br />
12.2 370<br />
12.2.1 371<br />
371<br />
372<br />
374<br />
12.2.2 374<br />
12.2.3 381<br />
382<br />
382<br />
12.2.4 385<br />
12.3 386<br />
12.3.1 386<br />
12.3.2 389<br />
390<br />
12 / 565
12.3.3 390<br />
12.3.4 392<br />
12.4 392<br />
<strong>wxPython</strong> 394<br />
13 395<br />
13.1 395<br />
13.1.1 396<br />
13.1.2 397<br />
13.1.3 399<br />
13.1.4 401<br />
13.1.5 403<br />
13.2 404<br />
13.2.1 404<br />
404<br />
405<br />
406<br />
13.2.2 407<br />
407<br />
407<br />
408<br />
408<br />
13.3 410<br />
13.3.1 410<br />
13.3.2 411<br />
13.4 417<br />
13.4.1 417<br />
13.4.2 418<br />
13 / 565
419<br />
419<br />
mix<strong>in</strong> 419<br />
13.4.3 423<br />
13.5 426<br />
13.6 430<br />
14 (grid) 432<br />
14.1 432<br />
14.1.1 433<br />
14.1.2 435<br />
14.2 439<br />
14.2.1 439<br />
14.2.2 440<br />
14.2.3 443<br />
445<br />
445<br />
446<br />
14.2.4 447<br />
14.2.5 449<br />
14.3 452<br />
14.3.1 452<br />
(renderer) 453<br />
454<br />
14.3.2 456<br />
14.3.3 457<br />
457<br />
458<br />
14 / 565
14.4 462<br />
14.4.1 462<br />
14.4.2 465<br />
14.5 466<br />
15 (tree control) 468<br />
15.1 468<br />
15.1.1 root() 481<br />
15.1.2 482<br />
15.1.3 482<br />
15.2 483<br />
15.3 485<br />
15.4 486<br />
15.5 488<br />
15.6 490<br />
15.7 490<br />
491<br />
494<br />
15.8 495<br />
15.9 496<br />
15.10 497<br />
15.11 501<br />
16 HTML 503<br />
16.1 HTML 503<br />
16.1.1 <strong>wxPython</strong>HTML 503<br />
16.1.2 URLHTML 506<br />
16.2 HTML 508<br />
15 / 565
16.2.1 508<br />
16.2.2 HTML 509<br />
16.2.3 510<br />
16.2.4 HTML 512<br />
wx.html.HtmlEasyPr<strong>in</strong>t<strong>in</strong>g 512<br />
513<br />
513<br />
513<br />
16.3 HTML 513<br />
16.3.1 HTML(parser) 514<br />
16.3.2 515<br />
16.3.3 519<br />
16.3.4 HTML 520<br />
16.4 521<br />
17 <strong>wxPython</strong> 522<br />
17.1 <strong>wxPython</strong> 522<br />
17.1.1 523<br />
17.1.2 524<br />
17.1.3 wx.Pr<strong>in</strong>tout 531<br />
17.2 532<br />
17.2.1 532<br />
533<br />
533<br />
17.3 535<br />
17.3.1 535<br />
17.3.2 536<br />
17.4 538<br />
16 / 565
538<br />
wx.Pr<strong>in</strong>ter 538<br />
wx.Pr<strong>in</strong>terPr<strong>in</strong>t () 538<br />
17.5 539<br />
539<br />
539<br />
540<br />
17.6 540<br />
18 <strong>wxPython</strong> 541<br />
18.1 541<br />
18.1.1 541<br />
18.1.2 542<br />
18.1.3 543<br />
18.1.4 543<br />
18.1.5 546<br />
1 547<br />
2 547<br />
3 548<br />
4 548<br />
18.2.1 548<br />
18.3 551<br />
18.3.1 551<br />
18.3.2 553<br />
18.4 555<br />
18.4.1 555<br />
18.4.2 556<br />
18.4.3 556<br />
17 / 565
18.5 wx.Timer 557<br />
18.5.1 EVT_TIMER 557<br />
557<br />
558<br />
558<br />
559<br />
18.5.2 560<br />
18.6 <strong>wxPython</strong> 560<br />
18.6.1 wx.CallAfter() 561<br />
18.6.2 564<br />
18.6.3 564<br />
18.7 565<br />
18 / 565
Part1 <strong>wxPython</strong><br />
1. <strong>wxPython</strong><br />
<br />
<br />
#!/b<strong>in</strong>/env python<br />
import wx<br />
class MyFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, -1, ”My Frame”, size=(300, 300))<br />
panel = wx.Panel(self, -1)<br />
panel.B<strong>in</strong>d(wx.EVT_MOTION, self.OnMove)<br />
wx.StaticText(panel, -1, ”Pos:”, pos=(10, 12))<br />
self.posCtrl = wx.TextCtrl(panel, -1, ””, pos=(40, 10))<br />
def OnMove(self, event):<br />
pos = event.GetPosition()<br />
self.posCtrl.SetValue(“%s, %s” % (pos.x, pos.y))<br />
if __name__ == ’__ma<strong>in</strong>__’:<br />
app = wx.PySimpleApp()<br />
frame = MyFrame()<br />
frame.Show(True)<br />
app.Ma<strong>in</strong>Loop()<br />
<br />
GUI<strong>wxPython</strong><br />
PythonPythongui<br />
<br />
19 / 565
1.1 <strong>wxPython</strong><br />
<br />
1wxPthon<br />
2<br />
3<strong>wxPython</strong>logo<br />
<br />
1.2 <strong>wxPython</strong><br />
bare.py<br />
import wx #1<br />
class App(wx.App): #2<br />
def OnInit(self): #3<br />
frame = wx.Frame(parent=None, title=’Bare’)<br />
frame.Show()<br />
return True<br />
app = App() #4<br />
app.Ma<strong>in</strong>Loop() #5<br />
20 / 565
<strong>wxPython</strong><br />
<strong>wxPython</strong><br />
1<strong>wxPython</strong><br />
2<strong>wxPython</strong><br />
3<br />
4<br />
5<br />
<br />
1.2.1 <strong>wxPython</strong><br />
<strong>wxPython</strong>wx:<br />
import wx<br />
<strong>wxPython</strong>wx<br />
<br />
class App(wx.App):<br />
<br />
<strong>wxPython</strong><br />
wx<br />
<strong>wxPython</strong>wxfrom <strong>wxPython</strong> import wxwx<br />
from <strong>wxPython</strong>.wx import *<br />
Pythonwx<br />
wx<br />
21 / 565
import*<strong>wxPython</strong><br />
<br />
<strong>wxPython</strong>Python<br />
import*<br />
from <strong>wxPython</strong> import wx<br />
wxwx.wxW<strong>in</strong>dow<br />
<strong>wxPython</strong><br />
<strong>wxPython</strong><strong>wxPython</strong><br />
wx<strong>wxPython</strong><strong>wxPython</strong><br />
<strong>wxPython</strong>xrcwx<br />
<br />
import wx<br />
from wx import xrc<br />
<strong>wxPython</strong>Python<br />
<br />
import sys<br />
import wx<br />
import os<br />
from wx import xrc<br />
import urllib<br />
1.2.2 <br />
wxapplication<br />
frame<strong>wxPython</strong>application<br />
frameapplicationwx.AppOnInit()<br />
OnInit()<br />
wx.App<br />
22 / 565
wx.App<br />
class MyApp(wx.App):<br />
def OnInit(self):<br />
frame = wx.Frame(parent=None, id=-1, title=”Bare”)<br />
frame.Show()<br />
return True<br />
MyAppOnInit()<br />
framewx.Frame<br />
<br />
Show()frameShow()<br />
frame<br />
frame.Show(False) # .<br />
frame.Show(True) # True.<br />
frame.Hide() # frame.Show(False)<br />
<br />
__<strong>in</strong>it__()Python<br />
wx.App.__<strong>in</strong>it()__<br />
__<strong>in</strong>it__()__<strong>in</strong>it()__<br />
class App(wx.App):<br />
def __<strong>in</strong>it__(self):<br />
wx.App.__<strong>in</strong>it__(self)<br />
<strong>wxPython</strong>OnInit()<br />
<br />
wx.AppMa<strong>in</strong>Loop()<br />
app = App()<br />
app.Ma<strong>in</strong>Loop()<br />
23 / 565
<strong>wxPython</strong><strong>wxPython</strong> GUI<br />
<br />
app.Ma<strong>in</strong>Loop()<br />
1.3 <strong>wxPython</strong><br />
Python<br />
<br />
spare.py<br />
#!/usr/b<strong>in</strong>/env python #1<br />
“””Spare.py is a start<strong>in</strong>g po<strong>in</strong>t for a <strong>wxPython</strong> program.””” #2<br />
import wx<br />
class Frame(wx.Frame): #3<br />
pass<br />
class App(wx.App):<br />
def OnInit(self):<br />
self.frame = Frame(parent=None, title=’Spare’) #4<br />
self.frame.Show()<br />
self.SetTopW<strong>in</strong>dow(self.frame) #5<br />
return True<br />
if __name__ == ’__ma<strong>in</strong>__’: #6<br />
app = App()<br />
app.Ma<strong>in</strong>Loop()<br />
14<br />
<br />
#1 l<strong>in</strong>uxunix<br />
<br />
chmod<br />
24 / 565
% spare.py<br />
<br />
#2 <br />
__doc__<br />
Python<br />
>>> import spare<br />
>>> pr<strong>in</strong>t spare.__doc__<br />
Spare.py is a start<strong>in</strong>g po<strong>in</strong>t for simple <strong>wxPython</strong> programs.<br />
>>><br />
#3 framebare<br />
wx.FramespareFrame<br />
wx.Frame<br />
Frame<br />
#4 frame<br />
#5 OnInit()AppSetTopW<strong>in</strong>dow()<br />
frameSetTopW<strong>in</strong>dow()<br />
wx.AppSetTopW<strong>in</strong>dow()<strong>wxPython</strong><br />
<strong>wxPython</strong><br />
<br />
#6 Python<br />
__name__<br />
if __name__ == ’__ma<strong>in</strong>__’:<br />
app = App()<br />
app.Ma<strong>in</strong>Loop()<br />
25 / 565
1.4 hello.py<br />
<br />
#!/usr/b<strong>in</strong>/env python<br />
“””Hello, <strong>wxPython</strong>! program.”””<br />
import wx<br />
class Frame(wx.Frame): #2 wx.Frame<br />
”””Frame class that displays an image.”””<br />
def __<strong>in</strong>it__(self, image, parent=None, id=-1,<br />
pos=wx.DefaultPosition,<br />
title=’Hello, <strong>wxPython</strong>!’): #3<br />
”””Create a Frame <strong>in</strong>stance and display image.”””<br />
#4 <br />
temp = image.ConvertToBitmap()<br />
size = temp.GetWidth(), temp.GetHeight()<br />
wx.Frame.__<strong>in</strong>it__(self, parent, id, title, pos, size)<br />
self.bmp = wx.StaticBitmap(parent=self, bitmap=temp)<br />
class App(wx.App): #5 wx.App<br />
”””Application class.”””<br />
def OnInit(self):<br />
#6 <br />
image = wx.Image(‘<strong>wxPython</strong>.jpg’, wx.BITMAP_TYPE_JPEG)<br />
self.frame = Frame(image)<br />
self.frame.Show()<br />
self.SetTopW<strong>in</strong>dow(self.frame)<br />
return True<br />
def ma<strong>in</strong>(): #7<br />
app = App()<br />
app.Ma<strong>in</strong>Loop()<br />
26 / 565
if __name__ == ’__ma<strong>in</strong>__’:<br />
ma<strong>in</strong>()<br />
<br />
#2 wx.Frame<br />
#3 <br />
<br />
wx.Frame.__<strong>in</strong>it__()<br />
#4 wx.StaticBitmap<br />
size<br />
sizewx.Frame.__<strong>in</strong>it__()<br />
#5 OnInit()wx.App<strong>wxPython</strong><br />
<br />
#6 hello.py<strong>wxPython</strong>.jpg<br />
<br />
#7 ma<strong>in</strong>()<strong>wxPython</strong><br />
27 / 565
2<strong>wxPython</strong><br />
<br />
<strong>wxPython</strong><br />
<br />
<strong>wxPython</strong><br />
<br />
2.1 <br />
<br />
<strong>wxPython</strong><br />
<strong>wxPython</strong><br />
<br />
<br />
web<br />
<br />
<br />
28 / 565
2.2 <br />
<strong>wxPython</strong><br />
wx.App<br />
<br />
<strong>wxPython</strong><br />
<strong>wxPython</strong><br />
wx.App<br />
<br />
<br />
<br />
<strong>wxPython</strong><br />
2.2.1 wx.App<br />
wx.App<br />
wx.App<br />
wx.App<br />
1<br />
2OnInit()<br />
3<br />
4Ma<strong>in</strong>Loop()<br />
<strong>wxPython</strong><br />
OnInit()<br />
<strong>wxPython</strong><br />
False<br />
<br />
<br />
OnInit()<strong>wxPython</strong><br />
OnInit()Python<br />
__<strong>in</strong>it____<strong>in</strong>it__<br />
__<strong>in</strong>it____<strong>in</strong>it__<br />
29 / 565
wx.App.__<strong>in</strong>it__(self)<br />
OnInit()<br />
Show()SetTopW<strong>in</strong>dow()<br />
<br />
<br />
<br />
wx.App<br />
OnInit()<br />
wx.App<br />
<strong>wxPython</strong>wx.PySimpleApp<br />
OnInit()wx.PySimpleApp<br />
class PySimpleApp(wx.App):<br />
def __<strong>in</strong>it__(self, redirect=False, filename=None,<br />
useBestVisual=False, clearSigInt=True):<br />
wx.App.__<strong>in</strong>it__(self, redirect, filename, useBestVisual,<br />
clearSigInt)<br />
def OnInit(self):<br />
return True<br />
wx.PySimpleApp<br />
if __name__ == ’__ma<strong>in</strong>__’:<br />
app = wx.PySimpleApp()<br />
frame = MyNewFrame(None)<br />
frame.Show(True)<br />
app.Ma<strong>in</strong>Loop()<br />
wx.PySimpleApp<br />
wx.PySimpleAppOnInit<br />
<br />
MyNewFrame<br />
<br />
30 / 565
wx.PySimpleApp<strong>wxPython</strong><br />
<br />
wx.PySimpleApp<br />
2.2.2 <br />
<strong>wxPython</strong><br />
<strong>wxPython</strong><br />
PythonPython<strong>wxPython</strong><br />
<strong>wxPython</strong>Ma<strong>in</strong>Loop()<br />
<strong>wxPython</strong><br />
wx.App<br />
OnInit()——<br />
<br />
OnInit()<br />
OnInit()Ma<strong>in</strong>Loop()<strong>wxPython</strong><br />
<br />
Ma<strong>in</strong>Loop()<br />
<br />
2.3 <strong>wxPython</strong><br />
Python<br />
sys.stdoutsys.stderrPython<br />
31 / 565
<strong>wxPython</strong><br />
W<strong>in</strong>dows<br />
<strong>wxPython</strong>Unix<strong>wxPython</strong><br />
<br />
<br />
<br />
2.3.1 <br />
<strong>wxPython</strong><br />
<strong>wxPython</strong>wxPyton<br />
Python<br />
stdout/stderr<br />
#!/usr/b<strong>in</strong>/env python<br />
import wx<br />
import sys<br />
class Frame(wx.Frame):<br />
def __<strong>in</strong>it__(self, parent, id, title):<br />
pr<strong>in</strong>t ”Frame __<strong>in</strong>it__”<br />
wx.Frame.__<strong>in</strong>it__(self, parent, id, title)<br />
class App(wx.App):<br />
def __<strong>in</strong>it__(self, redirect=True, filename=None):<br />
pr<strong>in</strong>t ”App __<strong>in</strong>it__”<br />
wx.App.__<strong>in</strong>it__(self, redirect, filename)<br />
def OnInit(self):<br />
pr<strong>in</strong>t ”OnInit” #stdout<br />
self.frame = Frame(parent=None, id=-1, title=’Startup’) #<br />
self.frame.Show()<br />
self.SetTopW<strong>in</strong>dow(self.frame)<br />
pr<strong>in</strong>t >> sys.stderr, ”A pretend error message” #stderr<br />
return True<br />
def OnExit(self):<br />
32 / 565
pr<strong>in</strong>t ”OnExit”<br />
if __name__ == ’__ma<strong>in</strong>__’:<br />
app = App(redirect=True) #1 <br />
pr<strong>in</strong>t ”before Ma<strong>in</strong>Loop”<br />
app.Ma<strong>in</strong>Loop() #2 <br />
pr<strong>in</strong>t ”after Ma<strong>in</strong>Loop”<br />
<br />
#1 stderrstdout<br />
<strong>wxPython</strong>redirect=True<br />
#2 <br />
<br />
stdoutstderr<br />
<br />
App __<strong>in</strong>it__<br />
after Ma<strong>in</strong>Loop<br />
<br />
<br />
2.2“Start Script”<br />
__ma<strong>in</strong>__“Application obect created”,<br />
app = App(redirect=True)wx.App.__<strong>in</strong>it__()<br />
OnInit()<strong>wxPython</strong><br />
wx.Frame.__<strong>in</strong>it__()wx.Frame<br />
__ma<strong>in</strong>__Ma<strong>in</strong>Loop()“Ma<strong>in</strong>Loop() called”<br />
wx.App.OnExit()<strong>wxPython</strong><br />
“Application object destroyed”<br />
33 / 565
OnExit()<br />
<strong>wxPython</strong><br />
<br />
2.3.2 <br />
<strong>wxPython</strong><br />
redirectTrueFalse<br />
redirectTruefilename<br />
filename<strong>wxPython</strong><br />
app = App(redirect=True)app = App(False)<br />
<br />
App __<strong>in</strong>it__<br />
OnInit<br />
Frame __<strong>in</strong>it__<br />
A pretend error message<br />
before Ma<strong>in</strong>Loop<br />
OnExit<br />
after Ma<strong>in</strong>Loop<br />
OnExit()<br />
<br />
app = App(True, ”output”)<br />
output<br />
“App__<strong>in</strong>it”“after Ma<strong>in</strong>Loop”<br />
wx.App<br />
2.4 <strong>wxPython</strong><br />
<strong>wxPython</strong><br />
<br />
SetTopW<strong>in</strong>dow()<strong>wxPython</strong><br />
<strong>wxPython</strong><br />
SetTopW<strong>in</strong>dow()<br />
<br />
Close()<br />
34 / 565
2.4.1 <br />
<strong>wxPython</strong><br />
<br />
wx.AppOnExit()<strong>wxPython</strong><br />
OnExit()<strong>wxPython</strong><br />
wx.Exit()<strong>wxPython</strong><br />
OnExit()<br />
<strong>wxPython</strong><br />
wx.AppSetExitOnFrameDelete(flag)<br />
flagFalse<strong>wxPython</strong><br />
wx.App<br />
<strong>wxPython</strong><br />
wx.Exit()<br />
2.4.2 <br />
<br />
<br />
<br />
<strong>wxPython</strong><br />
wx.AppExitMa<strong>in</strong>Loop()<br />
Ma<strong>in</strong>Loop()<br />
<br />
wx.Exit()<br />
<br />
<br />
<br />
wx.EVT_QUERY_END_SESSION<br />
<strong>wxPython</strong><br />
eventwx.CloseEvent<br />
CanVeto()CanVeto()Veto()<br />
<br />
wx.EVT_QUERY_END_SESSIONClose()<br />
wx.EVT_CLOSE<br />
35 / 565
Close()False<br />
<br />
2.5 <br />
<br />
<br />
<br />
<br />
<br />
wx.Framewx.Dialog<br />
wx.Frame<br />
wx.Dialog<br />
<br />
“”<br />
<br />
<br />
SetTopW<strong>in</strong>dow()<strong>wxPython</strong>SetTopW<strong>in</strong>dow()<br />
wx.App<br />
<br />
SetTopW<strong>in</strong>dow()<br />
<br />
2.5.1 wx.Frame<br />
<strong>wxPython</strong><br />
<br />
<strong>wxPython</strong>wx.Frame<br />
wx.Frame<br />
wx.Frame<br />
wx.Frame.__<strong>in</strong>it__()wx.Frame<br />
wx.Frame(parent, id=-1, title=””, pos=wx.DefaultPosition,<br />
size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE,<br />
name=”frame”)<br />
36 / 565
parentNone<br />
<br />
<br />
id<strong>wxPython</strong> ID-1<br />
<strong>wxPython</strong>ID<br />
title<br />
poswx.Po<strong>in</strong>t<br />
(0,0)(-1,-1)<br />
<br />
sizewx.Size(-1,-1)<br />
<br />
style<br />
name<br />
wx.Frame.__<strong>in</strong>it__()<br />
wx.Frame<br />
class MyFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, -1, ”My Friendly W<strong>in</strong>dow”,<br />
(100, 100), (100, 100))<br />
2.5.2 <strong>wxPython</strong>ID<br />
<strong>wxPython</strong>ID<strong>wxPython</strong><br />
ID<br />
ID<br />
ID<strong>wxPython</strong><br />
IDwx.ID_OK<br />
wx.ID_CANCELOKCancelID<br />
ID<strong>wxPython</strong><br />
ID<br />
<br />
37 / 565
ID<br />
1<br />
2wx.NewId()<br />
3wx.ID_ANY-1<br />
<br />
<br />
IDID<br />
wx.RegisterId()<strong>wxPython</strong><br />
ID<strong>wxPython</strong> ID<br />
wx.ID_LOWESTwx.ID_HIGHESTID<br />
<br />
IDwx.NewId()<strong>wxPython</strong><br />
ID<br />
id = wx.NewId()<br />
frame = wx.Frame.__<strong>in</strong>it__(None, id)<br />
wx.ID_ANY-1<br />
<strong>wxPython</strong>IDIDGetId()<br />
<br />
frame = wx.Frame.__<strong>in</strong>it__(None, -1)<br />
id = frame.GetId()<br />
2.5.3 wx.Sizewx.Po<strong>in</strong>t<br />
wx.Framewx.Sizewx.Po<strong>in</strong>t<br />
<strong>wxPython</strong><br />
wx.Po<strong>in</strong>txyx,y<br />
0Set(x,y)Get()xy<br />
Get()xy<br />
po<strong>in</strong>t = wx.Po<strong>in</strong>t(10, 12)<br />
x = po<strong>in</strong>t.x<br />
38 / 565
y = po<strong>in</strong>t.y<br />
wx.Po<strong>in</strong>tPython<br />
<br />
a = wx.Po<strong>in</strong>t(2, 3)<br />
b = wx.Po<strong>in</strong>t(5, 7)<br />
c = a + b<br />
bigger = a > b<br />
wx.Po<strong>in</strong>t<br />
wx.RealPo<strong>in</strong>twx.Po<strong>in</strong>t<br />
wx.Sizewx.Po<strong>in</strong>twidthheight<br />
wx.Sizewx.Po<strong>in</strong>t<br />
wx.Po<strong>in</strong>twx.Size<br />
<br />
<strong>wxPython</strong>wx.Po<strong>in</strong>twx.Size<br />
frame = wx.Frame(None, -1, pos=(10, 10), size=(100, 100))<br />
2.5.4 wx.Frame<br />
<strong>wxPython</strong><br />
wx.Frame<strong>wxPython</strong><br />
SetStyle()<br />
wx.MINIMIZE_BOX<br />
|<br />
wx.DEFAULT_FRAME_STYLE<br />
<br />
wx.MAXIMIZE_BOX | wx.MINIMIZE_BOX | wx.RESIZE_BORDER |<br />
wx.SYSTEM_MENU | wx.CAPTION | wx.CLOSE_BOX<br />
^<br />
<br />
<br />
39 / 565
wx.DEFAULT_FRAME_STYLE ^ (wx.RESIZE_BORDER | wx.MINIMIZE_BOX<br />
|wx.MAXIMIZE_BOX)<br />
&<br />
<br />
2.2wx.Frame<br />
wx.CAPTION<br />
wx.CLOSE_BOX<br />
<br />
wx.DEFAULT_FRAME_STYLE<br />
wx.FRAME_SHAPEDSetShape()<br />
<br />
wx.FRAME_TOOL_WINDOW<br />
W<strong>in</strong>dows<br />
<br />
wx.MAXIMIZE_BOX<br />
<br />
wx.MINIMIZE_BOX<br />
<br />
wx.RESIZE_BORDER<br />
wx.SIMPLE_BORDER<br />
wx.SYSTEM_MENU<br />
<br />
wx.MAXIMIZE_BOX, wx.MINIMIZE_BOXwx.CLOSE_BOX<br />
<br />
40 / 565
2.4wx.DEFAULT_STYLE<br />
2.5<br />
wx.DEFAULT_FRAME_STYLE ^ (wx.RESIZE_BORDER | wx.MINIMIZE_BOX |<br />
wx.MAXIMIZE_BOX)<br />
2.6<br />
wx.DEFAULT_FRAME_STYLE | wx.FRAME_TOOL_WINDOW<br />
2.7 wx.help.FRAME_EX_CONTEXTHELP<br />
2.6 <br />
wx.Frame<br />
<br />
41 / 565
2.6.1 <br />
2.8wx.FrameInsertFrameclose<br />
2.3InsertFrame<br />
2.3<br />
#!/usr/b<strong>in</strong>/env python<br />
import wx<br />
class InsertFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self, parent, id):<br />
wx.Frame.__<strong>in</strong>it__(self, parent, id, ’Frame With Button’,<br />
size=(300, 100))<br />
panel = wx.Panel(self) #<br />
button = wx.Button(panel, label=”Close”, pos=(125, 10),<br />
size=(50, 50)) #<br />
#<br />
self.B<strong>in</strong>d(wx.EVT_BUTTON, self.OnCloseMe, button)<br />
#<br />
self.B<strong>in</strong>d(wx.EVT_CLOSE, self.OnCloseW<strong>in</strong>dow)<br />
def OnCloseMe(self, event):<br />
self.Close(True)<br />
def OnCloseW<strong>in</strong>dow(self, event):<br />
self.Destroy()<br />
if __name__ == ’__ma<strong>in</strong>__’:<br />
app = wx.PySimpleApp()<br />
frame = InsertFrame(parent=None, id=-1)<br />
42 / 565
frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
InsertFrame__<strong>in</strong>it__wx.Panel<br />
wx.Button<br />
<br />
<br />
wx.Framewx.Panel<br />
<br />
tabwx.Panelwx.Frame<br />
UI<br />
<strong>wxPython</strong><br />
2.3<br />
2.3wx.Button<br />
wx.Panel<strong>wxPython</strong><br />
2.3wx.Panel<br />
<br />
<br />
panel<br />
<br />
panel<br />
<br />
<br />
<strong>wxPython</strong>sizers<br />
43 / 565
2.6.2 <br />
2.9<br />
2.4__<strong>in</strong>it__<br />
2.4<br />
#!/usr/b<strong>in</strong>/env python<br />
import wx<br />
import images<br />
class ToolbarFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self, parent, id):<br />
wx.Frame.__<strong>in</strong>it__(self, parent, id, ’Toolbars’,<br />
size=(300, 200))<br />
panel = wx.Panel(self)<br />
panel.SetBackgroundColour(‘White’)<br />
statusBar = self.CreateStatusBar() #1 <br />
toolbar = self.CreateToolBar() #2 <br />
toolbar.AddSimpleTool(wx.NewId(), images.getNewBitmap(),<br />
”New”, ”Long help for ’New’”) #3 <br />
toolbar.Realize() #4 <br />
menuBar = wx.MenuBar() # <br />
# <br />
menu1 = wx.Menu()<br />
menuBar.Append(menu1, ”&File”)<br />
menu2 = wx.Menu()<br />
#6 <br />
menu2.Append(wx.NewId(), ”&Copy”, ”Copy <strong>in</strong> status bar”)<br />
menu2.Append(wx.NewId(), ”C&ut”, ””)<br />
44 / 565
menu2.Append(wx.NewId(), ”Paste”, ””)<br />
menu2.AppendSeparator()<br />
menu2.Append(wx.NewId(), ”&Options...”, ”Display Options”)<br />
menuBar.Append(menu2, ”&Edit”) # <br />
self.SetMenuBar(menuBar) # <br />
if __name__ == ’__ma<strong>in</strong>__’:<br />
app = wx.PySimpleApp()<br />
frame = ToolbarFrame(parent=None, id=-1)<br />
frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
<br />
#1wx.StatusBar<br />
<br />
<br />
#2wx.ToolBar<br />
<br />
#3<br />
AddSimpleTool()ID<br />
<br />
#4Realize()<br />
<br />
#6ID<br />
<br />
2.7 <br />
<strong>wxPython</strong><br />
<br />
1<br />
2<br />
3<br />
45 / 565
<strong>wxPython</strong><br />
9<br />
<br />
wx.MessageDialog<br />
wx.MessageDialogOKyes/no<br />
yes/no<br />
dlg = wx.MessageDialog(None, ’Is this the coolest th<strong>in</strong>g ever!’,<br />
’MessageDialog’, wx.YES_NO | wx.ICON_QUESTION)<br />
result = dlg.ShowModal()<br />
dlg.Destroy()<br />
2.10<br />
wx.MessageDialog<br />
wx.MessageDialog(parent, message,<br />
caption=”Message box”,<br />
style=wx.OK | wx.CANCEL,<br />
pos=wx.DefaultPosition)<br />
<br />
parentNone<br />
message<br />
caption<br />
style<br />
pos<br />
46 / 565
ShowModal()<br />
ShowModal()<br />
wx.MessageDialog<br />
wx.ID_YES, wx.ID_NO, wx.ID_CANCEL, wx.ID_OK<br />
<br />
<br />
wx.TextEntryDialogOK<br />
<br />
dlg = wx.TextEntryDialog(None, ”Who is buried <strong>in</strong> Grant’s tomb”,<br />
’A Question’, ’Cary Grant’)<br />
if dlg.ShowModal() == wx.ID_OK:<br />
response = dlg.GetValue()<br />
2.11<br />
wx.TextEntryDialog<br />
“Please enter text”<br />
wx.OK | wx.CANCELwx.MessageDialog<br />
ShowModal()IDGetValue()<br />
SetValue()<br />
<br />
<br />
wx.S<strong>in</strong>gleChoiceDialog<br />
dlg = wx.S<strong>in</strong>gleChoiceDialog(None,<br />
’What version of Python are you us<strong>in</strong>g’,<br />
’S<strong>in</strong>gle Choice’,<br />
[‘1.5.2’, ’2.0’, ’2.1.3’, ’2.2’, ’2.3.1’],<br />
47 / 565
if dlg.ShowModal() == wx.ID_OK:<br />
response = dlg.GetStr<strong>in</strong>gSelection()<br />
2.12<br />
wx.S<strong>in</strong>gleChoiceDialog<br />
GetSelection()<br />
GetStr<strong>in</strong>gSelection()<br />
2.8 <br />
<strong>wxPython</strong><br />
<br />
<br />
<br />
“unable to import module wx”<br />
<br />
<strong>wxPython</strong>PYTHONPATH<strong>wxPython</strong><br />
Python<strong>wxPython</strong>Python<br />
<br />
<br />
PythonUnixwhich python<br />
W<strong>in</strong>dows<strong>wxPython</strong><br />
Python/Lib/site-packages<br />
<strong>wxPython</strong><br />
48 / 565
wx.App<strong>wxPython</strong><br />
<br />
wx.App<br />
<br />
<br />
<br />
wx.AppMa<strong>in</strong>Loop()<br />
<br />
Ma<strong>in</strong>Loop()<br />
<br />
Ma<strong>in</strong>Loop()<br />
<br />
<br />
OnInit()OnInit()<br />
__<strong>in</strong>it__()<br />
<br />
Ma<strong>in</strong>Loop()<br />
<br />
redirect=False<br />
<br />
2.9 <br />
1<strong>wxPython</strong><br />
<strong>wxPython</strong>wx.App<br />
<br />
2OnInit()<br />
<strong>wxPython</strong><br />
<br />
3<strong>wxPython</strong><br />
<strong>wxPython</strong>stdoutstderr<br />
<strong>wxPython</strong><br />
<br />
49 / 565
4<strong>wxPython</strong>wx.Frame<br />
wx.FramestylewxWidget<br />
IDID<strong>wxPython</strong><br />
<br />
wx.PanelPanel<br />
<br />
<br />
5<br />
<br />
<br />
50 / 565
3<br />
<strong>wxPython</strong><br />
<br />
GUI<br />
<br />
<br />
<br />
<strong>wxPython</strong><br />
<br />
<strong>wxPython</strong><br />
<br />
<strong>wxPython</strong><br />
<br />
<strong>wxPython</strong><br />
<br />
3.1 <br />
event3.1<br />
<br />
(event)<br />
(event object)<strong>wxPython</strong><br />
wx.Eventwx.CommandEvent<br />
wx.MouseEvent<br />
(event type)<strong>wxPython</strong>ID<br />
wx.MouseEvent<br />
<br />
(event source)<strong>wxPython</strong><br />
<br />
(event-driven)<br />
(event queue)<br />
51 / 565
(event handler)<br />
<br />
(event b<strong>in</strong>der)<br />
<strong>wxPython</strong><br />
wx.EvtHandler<strong>wxPython</strong><br />
<br />
<br />
3.2 <br />
<strong>wxPython</strong><br />
PythonPython<br />
<br />
<br />
<strong>wxPython</strong><br />
<strong>wxPython</strong><strong>wxPython</strong><br />
3.1<br />
<br />
<br />
<br />
52 / 565
1<br />
<br />
<strong>wxPython</strong>wx.App.Ma<strong>in</strong>Loop()<br />
<br />
2<br />
<strong>wxPython</strong><br />
wx.Event<br />
<br />
<br />
3<br />
<strong>wxPython</strong><br />
<br />
<br />
<br />
4<br />
<strong>wxPython</strong>wx.Event<br />
wx.EvtHandler.ProcessEvent()<br />
3.3<br />
53 / 565
<strong>wxPython</strong><br />
<strong>wxPython</strong><br />
<br />
<strong>wxPython</strong><br />
“”<br />
3.2.1 <br />
<strong>wxPython</strong><br />
<br />
<br />
<br />
self.B<strong>in</strong>d(wx.EVT_BUTTON, self.OnClick, aButton)<br />
wx.EVT_BUTTONaButton<br />
self.OnClickB<strong>in</strong>d()<br />
wx.EvtHandlerwx.EvtHandler<br />
<br />
54 / 565
<strong>wxPython</strong><br />
wx.App.Ma<strong>in</strong>Loop()Ma<strong>in</strong>Loop()<br />
Python<br />
while True:<br />
while not self.Pend<strong>in</strong>g():<br />
self.ProcessIdle()<br />
self.DoMessage()<br />
<br />
<br />
3.2.2 <br />
<br />
<strong>wxPython</strong><br />
<br />
<br />
<br />
<br />
<br />
<br />
Python<strong>wxPython</strong><br />
<br />
3.2.3 <br />
<strong>wxPython</strong><br />
wx.ButtonEVT_BUTTON<br />
wx.CommandEvent<br />
<strong>wxPython</strong>wx.SizeEvent<br />
<br />
<br />
<br />
<strong>wxPython</strong>wx.Event<br />
wx.Event<br />
wx.Event<br />
55 / 565
<strong>wxPython</strong>wx.Event3.2<br />
<br />
3.2wx.Event<br />
wx.CloseEvent<br />
<br />
wx.CommandEvent<br />
<br />
wx.CommandEvent<br />
<br />
wx.KeyEvent<br />
<br />
wx.MouseEvent<br />
<br />
wx.Pa<strong>in</strong>tEvent<br />
wx.SizeEvent<br />
wx.TimerEventwx.Timer<br />
<br />
<br />
3.3 <br />
wx.PyEventB<strong>in</strong>der<br />
wx.PyEventB<strong>in</strong>der<br />
<br />
wx.Event<br />
<strong>wxPython</strong><br />
wx.EVT_C+<br />
+ wxWidgetswx.EVT<br />
wx.EventGetEventType()<br />
<br />
wx.EVTwx.MouseEvent<br />
<br />
<br />
wx.EVT_LEFT_DOWN<br />
wx.EVT_LEFT_UP<br />
wx.EVT_LEFT_DCLICK<br />
56 / 565
wx.EVT_MIDDLE_DOWN<br />
wx.EVT_MIDDLE_UP<br />
wx.EVT_MIDDLE_DCLICK<br />
wx.EVT_RIGHT_DOWN<br />
wx.EVT_RIGHT_UP<br />
wx.EVT_RIGHT_DCLICK<br />
wx.EVT_MOTION<br />
wx.ENTER_WINDOWwx.LEAVE_WINDOW<br />
wx.EVT_MOUSEWHEEL<br />
wx.EVT_MOUSE_EVENTS<br />
<br />
wx.CommandEvent28<br />
W<strong>in</strong>dows<br />
wx.EVT_BUTTONwx.EVT_MENU<br />
part2<br />
<strong>wxPython</strong><br />
<strong>wxPython</strong><br />
<br />
<strong>wxPython</strong><br />
<strong>wxPython</strong><br />
<strong>wxPython</strong><br />
wx.EvtHandlerwx.EvtHandler<br />
<strong>wxPython</strong>wx.EvtHandler<br />
wx.App<br />
<br />
<strong>wxPython</strong><br />
wx.EvtHandler<br />
3.3.1 wx.EvtHandler<br />
wx.EvtHandler<br />
wx.EvtHandlerB<strong>in</strong>d()<br />
B<strong>in</strong>d(event, handler, source=None, id=wx.ID_ANY, id2=wx.ID_ANY)<br />
B<strong>in</strong>d()<br />
event3.3wx.PyEventB<strong>in</strong>der<br />
57 / 565
handlerPython<br />
<br />
handlerNonesource<br />
<br />
None<br />
wx.Frame<br />
__<strong>in</strong>it__<br />
OKCancel<br />
source<strong>wxPython</strong><br />
self.B<strong>in</strong>d(wx.EVT_BUTTON, self.OnClick, button)<br />
3.1sourcesource<br />
<br />
def __<strong>in</strong>it__(self, parent, id):<br />
wx.Frame.__<strong>in</strong>it__(self, parent, id, ’Frame With Button’,<br />
size=(300, 100))<br />
panel = wx.Panel(self, -1)<br />
button = wx.Button(panel, -1, ”Close”, pos=(130, 15),<br />
size=(40, 40))<br />
self.B<strong>in</strong>d(wx.EVT_CLOSE, self.OnCloseW<strong>in</strong>dow) #1 <br />
self.B<strong>in</strong>d(wx.EVT_BUTTON, self.OnCloseMe, button) #2 <br />
def OnCloseMe(self, event):<br />
self.Close(True)<br />
def OnCloseW<strong>in</strong>dow(self, event):<br />
self.Destroy()<br />
<br />
#1 self.OnCloseW<strong>in</strong>dow<br />
source<br />
#2 self.OnCloseMe<br />
<strong>wxPython</strong><br />
source<br />
<br />
3.2<br />
58 / 565
#!/usr/b<strong>in</strong>/env python<br />
import wx<br />
class MenuEventFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self, parent, id):<br />
wx.Frame.__<strong>in</strong>it__(self, parent, id, ’Menus’,<br />
size=(300, 200))<br />
menuBar = wx.MenuBar()<br />
menu1 = wx.Menu()<br />
menuItem = menu1.Append(-1, ”&Exit...”)<br />
menuBar.Append(menu1, ”&File”)<br />
self.SetMenuBar(menuBar)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnCloseMe, menuItem)<br />
def OnCloseMe(self, event):<br />
self.Close(True)<br />
if __name__ == ’__ma<strong>in</strong>__’:<br />
app = wx.PySimpleApp()<br />
frame = MenuEventFrame(parent=None, id=-1)<br />
frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
B<strong>in</strong>d()idid2ID<br />
IDsourceID<br />
ID<br />
idid2IDID<br />
ID<br />
B<strong>in</strong>d()wx.Python2.5EVT_*<br />
<br />
wx.EVT_BUTTON(self, self.button.GetId(), self.OnClick)<br />
<br />
2.5wx.EVT*<br />
3.3wx.EvtHandler<br />
59 / 565
AddPend<strong>in</strong>gEvent(event)event<br />
ProcessEvent()<br />
<br />
B<strong>in</strong>d(event, handler, source=None, id=wx.ID_ANY, id2=wx.ID_ANY)<br />
3.3.1<br />
GetEvtHandlerEnabled()<br />
SetEvtHandlerEnabled( boolean)True<br />
False<br />
ProcessEvent(event)event<br />
60 / 565
3.4 <strong>wxPython</strong><br />
<br />
<strong>wxPython</strong><br />
3.2<br />
<br />
3.3<br />
<strong>wxPython</strong><br />
3.3<br />
#!/usr/b<strong>in</strong>/env python<br />
import wx<br />
class MouseEventFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self, parent, id):<br />
wx.Frame.__<strong>in</strong>it__(self, parent, id, ’Frame With Button’,<br />
size=(300, 100))<br />
self.panel = wx.Panel(self)<br />
self.button = wx.Button(self.panel,<br />
label=”Not Over”, pos=(100, 15))<br />
self.B<strong>in</strong>d(wx.EVT_BUTTON, self.OnButtonClick,<br />
self.button) #1 <br />
self.button.B<strong>in</strong>d(wx.EVT_ENTER_WINDOW,<br />
self.OnEnterW<strong>in</strong>dow) #2 <br />
self.button.B<strong>in</strong>d(wx.EVT_LEAVE_WINDOW,<br />
self.OnLeaveW<strong>in</strong>dow) #3 <br />
61 / 565
def OnButtonClick(self, event):<br />
self.panel.SetBackgroundColour(‘Green’)<br />
self.panel.Refresh()<br />
def OnEnterW<strong>in</strong>dow(self, event):<br />
self.button.SetLabel(“Over Me!”)<br />
event.Skip()<br />
def OnLeaveW<strong>in</strong>dow(self, event):<br />
self.button.SetLabel(“Not Over”)<br />
event.Skip()<br />
if __name__ == ’__ma<strong>in</strong>__’:<br />
app = wx.PySimpleApp()<br />
frame = MouseEventFrame(parent=None, id=-1)<br />
frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
<br />
MouseEventFrame<br />
#1<br />
#2<br />
#3<br />
<strong>wxPython</strong><br />
#1<strong>wxPython</strong><br />
#2#3<br />
<br />
<strong>wxPython</strong><br />
3.4.1 <br />
<strong>wxPython</strong><br />
<br />
<br />
<br />
62 / 565
3.3<br />
<strong>wxPython</strong><br />
<br />
<strong>wxPython</strong><br />
<br />
<strong>wxPython</strong><br />
<strong>wxPython</strong><br />
<strong>wxPython</strong><br />
<br />
<strong>wxPython</strong><br />
<br />
<br />
3.3<br />
63 / 565
<strong>wxPython</strong><br />
<strong>wxPython</strong>“<br />
”<br />
<br />
<br />
<br />
<br />
<br />
wx.EvtHandlerSetEvtHandlerEnabled(boolean)<br />
<br />
<br />
<br />
(UI)<br />
UIwx.W<strong>in</strong>dowDisable()<br />
Enable()UI<br />
UI<br />
<br />
wx.EvtHandler<br />
<br />
ProcessEvent()<br />
<strong>wxPython</strong><br />
ProcessEvent()wx.EvtHandler<br />
3.3ProcessEvent()<br />
64 / 565
ProcessEvent()True<br />
wx.EventSkip()<br />
wx.W<strong>in</strong>dow<br />
validatorValidator<br />
<br />
3.6<br />
ProcessEvent()<br />
<br />
65 / 565
<strong>wxPython</strong><br />
<br />
3.3wx.EVT_ENTER_WINDOW<br />
OnEnterW<strong>in</strong>dow()<br />
OnEnterW<strong>in</strong>dow()<br />
wx.EVT_LEFT_DOWN<strong>wxPython</strong><br />
<br />
3.7<br />
<strong>wxPython</strong><br />
wx.EventSkip()Skip()<br />
<br />
Skip()<br />
Skip()<br />
<strong>wxPython</strong>3.3OnButtonClick()Skip()<br />
<br />
Skip()“”<br />
<br />
66 / 565
3.8<br />
<strong>wxPython</strong><br />
<br />
<br />
<br />
Skip()<strong>wxPython</strong><br />
wx.App<br />
<br />
wx.DialogProcessEvent()<br />
True<br />
wx.Dialog<br />
<br />
<br />
wx.CommandEvent<br />
<br />
67 / 565
3.3wx.Button<br />
wx.EVT_BUTTONwx.EVT_BUTTON<br />
wx.CommandEvent<strong>wxPython</strong><br />
panelpanel<br />
panelframeframe<br />
ProcessEvent() OnButtonClick()<br />
<br />
wx.CommandEvent<br />
<br />
<strong>wxPython</strong><br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
wx.App<br />
ProcessEvent()wx.App<br />
GUI<br />
<br />
<br />
<br />
3.4.2 Skip()<br />
<br />
Skip()Skip()<br />
3.4.1<br />
<br />
3.4<br />
Skip()<br />
<br />
68 / 565
3.4 <br />
#!/usr/b<strong>in</strong>/env python<br />
import wx<br />
class DoubleEventFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self, parent, id):<br />
wx.Frame.__<strong>in</strong>it__(self, parent, id, ’Frame With Button’,<br />
size=(300, 100))<br />
self.panel = wx.Panel(self, -1)<br />
self.button = wx.Button(self.panel, -1, ”Click Me”, pos=(100, 15))<br />
self.B<strong>in</strong>d(wx.EVT_BUTTON, self.OnButtonClick,<br />
self.button) #1 <br />
self.button.B<strong>in</strong>d(wx.EVT_LEFT_DOWN, self.OnMouseDown) #2 <br />
<br />
def OnButtonClick(self, event):<br />
self.panel.SetBackgroundColour(‘Green’)<br />
self.panel.Refresh()<br />
def OnMouseDown(self, event):<br />
self.button.SetLabel(“Aga<strong>in</strong>!”)<br />
event.Skip() #3 <br />
if __name__ == ’__ma<strong>in</strong>__’:<br />
app = wx.PySimpleApp()<br />
frame = DoubleEventFrame(parent=None, id=-1)<br />
frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
#1 OnButtonClick()<br />
<br />
#2 OnMouseDown()<br />
<br />
self.button.B<strong>in</strong>dself.B<strong>in</strong>d<br />
69 / 565
wx.EVT_BUTTON#3Skip()<br />
DoubleEventFrameSkip()#2<br />
wx.EVT_BUTTONSkip()<br />
<br />
<strong>wxPython</strong><br />
Skip()<br />
<br />
3.5 <br />
wx.App<br />
<strong>wxPython</strong><br />
<br />
<br />
<br />
3.4wx.App<br />
Dispatch()Ma<strong>in</strong>Loop()<br />
<br />
Pend<strong>in</strong>g()<strong>wxPython</strong><br />
True<br />
Yield(onlyIfNeeded=False)wxWidgets<br />
<br />
TrueFalse<br />
onlyIfNeededTrue<br />
FalseYield<br />
wx.SafeYield()Yield<br />
Yield<br />
<br />
<br />
<br />
70 / 565
3.6 <br />
<br />
<br />
<strong>wxPython</strong><br />
<br />
<br />
<br />
<br />
3.6.1 <br />
3.9(panel)<br />
TwoButtonEvent<br />
<br />
<br />
1<strong>wxPython</strong>wx.PyEvent<br />
wx.PyCommandEvent<br />
<strong>wxPython</strong>pywxWidgetPython<br />
C++<br />
2<br />
3ProcessEvent()<br />
<br />
<strong>wxPython</strong><br />
71 / 565
3.5<br />
import wx<br />
class TwoButtonEvent(wx.PyCommandEvent): #1 <br />
def __<strong>in</strong>it__(self, evtType, id):<br />
wx.PyCommandEvent.__<strong>in</strong>it__(self, evtType, id)<br />
self.clickCount = 0<br />
def GetClickCount(self):<br />
return self.clickCount<br />
def SetClickCount(self, count):<br />
self.clickCount = count<br />
myEVT_TWO_BUTTON = wx.NewEventType() #2 <br />
EVT_TWO_BUTTON = wx.PyEventB<strong>in</strong>der(myEVT_TWO_BUTTON, 1) #3 <br />
<br />
class TwoButtonPanel(wx.Panel):<br />
def __<strong>in</strong>it__(self, parent, id=-1, leftText=”Left”,<br />
rightText=”Right”):<br />
wx.Panel.__<strong>in</strong>it__(self, parent, id)<br />
self.leftButton = wx.Button(self, label=leftText)<br />
self.rightButton = wx.Button(self, label=rightText,<br />
pos=(100,0))<br />
self.leftClick = False<br />
self.rightClick = False<br />
self.clickCount = 0<br />
<br />
#4 <br />
self.leftButton.B<strong>in</strong>d(wx.EVT_LEFT_DOWN, self.OnLeftClick)<br />
self.rightButton.B<strong>in</strong>d(wx.EVT_LEFT_DOWN, self.OnRightClick)<br />
def OnLeftClick(self, event):<br />
self.leftClick = True<br />
self.OnClick()<br />
event.Skip() #5 <br />
72 / 565
def OnRightClick(self, event):<br />
self.rightClick = True<br />
self.OnClick()<br />
event.Skip() #6 <br />
def OnClick(self):<br />
self.clickCount += 1<br />
if self.leftClick and self.rightClick:<br />
self.leftClick = False<br />
self.rightClick = False<br />
evt = TwoButtonEvent(myEVT_TWO_BUTTON, self.GetId()) #7 <br />
<br />
evt.SetClickCount(self.clickCount) # <br />
self.GetEventHandler().ProcessEvent(evt) #8 <br />
class CustomEventFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self, parent, id):<br />
wx.Frame.__<strong>in</strong>it__(self, parent, id, ’Click Count: 0’,<br />
size=(300, 100))<br />
panel = TwoButtonPanel(self)<br />
self.B<strong>in</strong>d(EVT_TWO_BUTTON, self.OnTwoClick, panel) #9 <br />
def OnTwoClick(self, event): #10 <br />
self.SetTitle(“Click Count: %s” % event.GetClickCount())<br />
if __name__ == ’__ma<strong>in</strong>__’:<br />
app = wx.PySimpleApp()<br />
frame = CustomEventFrame(parent=None, id=-1)<br />
frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
<br />
#1 wx.PyCommandEvent<br />
wx.PyEventwx.PyCommandEvent<strong>wxPython</strong><br />
C++Python<br />
wx.Event<strong>wxPython</strong><br />
73 / 565
C++Pythonwx.PyEventPython<br />
Python<br />
<br />
#2 wx.NewEventType()wx.NewId()<br />
ID<br />
#3 <br />
[0,2]wxId<br />
wx.EvtHandler.B<strong>in</strong>d()<br />
#4 <br />
<br />
OnLeftClick()OnRightClick()<br />
<br />
#5 #6 Skip()<br />
skip(self.OnClick())<br />
Skip()<br />
Skip()<strong>wxPython</strong><br />
<br />
<br />
#7 <br />
ID<br />
<br />
#8 ProcessEvent()<br />
ProcessEvent()3.4.1GetEventHandler()wx.EvtHandler<br />
<br />
wx.EvtHandler()<br />
<br />
#9 #3<br />
<br />
#10 <br />
74 / 565
<strong>wxPython</strong><br />
<strong>wxPython</strong><br />
<br />
3.7 <br />
1<strong>wxPython</strong><br />
<br />
2<strong>wxPython</strong>wx.Event<br />
<strong>wxPython</strong><br />
wx.CommandEvent<br />
<br />
3<strong>wxPython</strong>wx.PyEventB<strong>in</strong>der<br />
wx.PyEventB<strong>in</strong>der<br />
<strong>wxPython</strong>wx.EvtHandlerwx.EvtHandler<br />
B<strong>in</strong>d()<br />
<strong>wxPython</strong>ID<br />
B<strong>in</strong>d()<br />
4<br />
<br />
<br />
<br />
Skip()<br />
wx.App<br />
5<strong>wxPython</strong><br />
wx.PyEvent<br />
wx.PyCommandEvent<br />
<br />
ProcessEvent()<br />
<br />
<strong>wxPython</strong><br />
<strong>wxPython</strong><br />
<strong>wxPython</strong><br />
75 / 565
4PyCrust<strong>wxPython</strong><br />
PyCrustshell<strong>wxPython</strong><br />
<strong>wxPython</strong><br />
PyCrustPatrick O’Brien<strong>wxPython</strong><br />
Python shellPyShellPyCrust<br />
PyCrustPyPy<strong>wxPython</strong>Py<br />
PyFill<strong>in</strong>g, PyAlaMode, PyAlaCarte, <br />
PyShell <strong>wxPython</strong><br />
PyCrust<br />
PyCrust<br />
<strong>wxPython</strong>Python shell<br />
PyCrustPy<br />
4.1 <strong>wxPython</strong><br />
Python<br />
Python<br />
PythonPythonPython<br />
4.1PythonPython<br />
‘>>>’<br />
Python‘...’<br />
4.1 Python<br />
$ Python<br />
Python 2.3.3 (#1, Jan 25 2004, 11:06:18)<br />
[GCC 3.2.2 (Mandrake L<strong>in</strong>ux 9.1 3.2.2-3mdk)] on l<strong>in</strong>ux2<br />
Type ”help”, ”copyright”, ”credits” or ”license” for more <strong>in</strong>formation.<br />
>>> 2 + 2<br />
4<br />
>>> 7 * 6<br />
42<br />
>>> 5 ** 3<br />
125<br />
>>> for n <strong>in</strong> range(5):<br />
76 / 565
... pr<strong>in</strong>t n * 9<br />
...<br />
0<br />
9<br />
18<br />
27<br />
36<br />
>>><br />
Python<br />
Python<br />
PythonPython<br />
Python<br />
<br />
PythonPython shell<br />
shellDOSUnixbash<br />
<br />
Python shell4.1<br />
Pythonshell<br />
Python shell<br />
IDLEPython<br />
IDLE4.1<br />
77 / 565
IDLEPython shell<br />
PythonPythonW<strong>in</strong>Boa Constructor<br />
IDLEPython shellshell<br />
(recall)<br />
PyCrustPyCrust<br />
Python shell<br />
PyCrustGUI<br />
GUIIDLETk<strong>in</strong>ter<strong>wxPython</strong><br />
IDLEPython shell<strong>wxPython</strong><br />
<strong>wxPython</strong>Tk<strong>in</strong>ter<br />
<br />
78 / 565
<strong>wxPython</strong>Python shell<strong>wxPython</strong><br />
Python shellPyCrust<br />
<br />
4.2 PyCrust<br />
PyCrustshellPyCrustshell<br />
Python shell<br />
4.2PyCrust<br />
PyCrustwx.SplitterW<strong>in</strong>dow<br />
Python shell<br />
Notebook<br />
PyCrust shell<br />
<br />
79 / 565
4.2.1 <br />
PyCrust<br />
<br />
<br />
TabPyCrust<br />
4.3PyCrust<br />
<br />
4.3<br />
4.2.2 <br />
PyCrust<br />
4.4<br />
<br />
80 / 565
4.4<br />
4.2.3 <br />
shellPyCrust<br />
Python<br />
<br />
4.2.4 Python <br />
PyCrustPythonPython<br />
Python4.5<br />
81 / 565
4.5<br />
Python(help)help<br />
helpquitPython<br />
(>>>)<br />
4.2.5 <br />
PyCrust shell<br />
<br />
Python<br />
PyCrust<br />
Python<br />
4.1<br />
82 / 565
Ctrl+<br />
Alt+P<br />
Ctrl+<br />
Alt+N<br />
Shift+<br />
Shift+<br />
F8F8<br />
Ctrl+Enter<br />
<br />
PyCrustwxPythob<br />
<br />
<br />
EnterPython<br />
Ctrl+Enter<br />
<br />
<br />
<br />
EnterPyCrustPython<br />
Enter<br />
<br />
Python<br />
<br />
<br />
<br />
4.2.6 <br />
shell<br />
Python shell<br />
PyCrust4.2<br />
Ctrl+C<br />
Ctrl+Shift+C<br />
Ctrl+X<br />
Ctrl+V<br />
Ctrl+Shift+V<br />
83 / 565
PyCrustPyCrust shell<br />
Pythonemail<br />
PyCrust<br />
PyCrust<br />
<br />
shellPyCrust<br />
<br />
4.2.7 shell<br />
<strong>wxPython</strong>PyCrustPython shell<br />
PythonPyCrust shell<br />
PyCrust<br />
>>> while True:<br />
... pr<strong>in</strong>t ”Hello”<br />
...<br />
EnterPythonPyCrust<br />
PyCrust<br />
Python shellPython shell(Ctrl+C<br />
Python shell<br />
>>> while True:<br />
... pr<strong>in</strong>t ”Hello”<br />
...<br />
Hello<br />
Hello<br />
Hello<br />
Hello<br />
Hello<br />
Hello<br />
Hello<br />
Hello<br />
Hello<br />
Hello<br />
Hello<br />
Traceback (most recent call last):<br />
File ””, l<strong>in</strong>e 2, <strong>in</strong> <br />
84 / 565
KeyboardInterrupt<br />
>>><br />
GUIPyCrust<br />
shell<br />
PyCrust<br />
PyCrustshellPyCrust shell<br />
Python shell<br />
4.2.8 <br />
PyCrustPyCrustshell<br />
“”“”shell<br />
4.64.7<br />
<br />
85 / 565
4.6PyCrust<br />
4.6<br />
86 / 565
4.7<br />
4.7PyCrust<br />
4.3 PyCrust notebook<br />
PyCrustnotebooknotebook<br />
PyCrust“Namespace”<br />
4.3.1 Namespace<br />
4.8Namespacewx.SplitterW<strong>in</strong>dow<br />
<br />
<br />
87 / 565
4.8<br />
<br />
Pythonlocals()4.8<br />
wx<br />
PyCrust<br />
wx<strong>wxPython</strong>PyCrust__<strong>in</strong>it__.py<br />
wx<br />
88 / 565
PyCrust shellPyCrustlocale<br />
locale/encod<strong>in</strong>g_alias/’en’<br />
PyCrust shell<br />
>>> import locale<br />
>>> locale.encod<strong>in</strong>g_alias[‘en’]<br />
‘ISO8859-1’<br />
>>><br />
PyCrust locale.encod<strong>in</strong>g_alias[‘en’]<br />
Python[‘en’]encod<strong>in</strong>g_alias<br />
(list)<br />
PyCrust<br />
4.3.2 Display<br />
DisplayPyCrustpp()<br />
Pythonppr<strong>in</strong>t<br />
ppr<strong>in</strong>tDisplay<br />
PyCrust shell Display<br />
PyCrust shellpp()<br />
Display Display<br />
<br />
4.3.3 Calltip<br />
CalltipPython shell<br />
Calltip<strong>wxPython</strong><br />
<br />
wx.Button<br />
Calltipwx.Button<br />
__<strong>in</strong>it__(self, W<strong>in</strong>dow parent, <strong>in</strong>t id=-1, Str<strong>in</strong>g label=EmptyStr<strong>in</strong>g,<br />
Po<strong>in</strong>t pos=DefaultPosition, Size size=DefaultSize,<br />
long style=0, Validator validator=DefaultValidator,<br />
Str<strong>in</strong>g name=ButtonNameStr) -> Button<br />
Create and show a button. The preferred way to create standard buttons<br />
89 / 565
is to use a standard ID and an empty label. In this case wxWigets will<br />
automatically use a stock label that corresponds to the ID given. In<br />
addition, the button will be decorated with stock icons under GTK+2.<br />
<strong>wxPython</strong>C++<br />
C++<br />
PythonPyCrust<br />
4.3.4 Session<br />
Sessionshell<br />
<br />
4.3.5 Dispatcher <br />
PyCrustdispatcher<br />
PyCrustdispatcher<br />
shellPython4.9Dispatcher<br />
PyCrust<br />
90 / 565
4.9<br />
Dispatcherwx.Notebook<br />
Dispatcher<br />
dispatcher<br />
class DispatcherList<strong>in</strong>g(wx.TextCtrl):<br />
”””Text control conta<strong>in</strong><strong>in</strong>g all dispatches for session.”””<br />
def __<strong>in</strong>it__(self, parent=None, id=-1):<br />
style = (wx.TE_MULTILINE | wx.TE_READONLY |<br />
wx.TE_RICH2 | wx.TE_DONTWRAP)<br />
wx.TextCtrl.__<strong>in</strong>it__(self, parent, id, style=style)<br />
dispatcher.connect(receiver=self.spy)<br />
def spy(self, signal, sender):<br />
”””Receiver for Any signal from Any sender.”””<br />
text = ’%r from %s’ % (signal, sender)<br />
self.SetInsertionPo<strong>in</strong>tEnd()<br />
start, end = self.GetSelection()<br />
if start != end:<br />
self.SetSelection(0, 0)<br />
self.AppendText(text + ’\n’)<br />
91 / 565
PyCrustPython shell<br />
<strong>wxPython</strong>PyCrust<br />
4.4 PyCrust<strong>wxPython</strong><br />
<strong>wxPython</strong><br />
PyCrust<br />
<br />
PyWrapPyCrust shell<br />
4.2spare.py<br />
PyCrust<br />
4.2<br />
#!/usr/b<strong>in</strong>/env python<br />
“””Spare.py is a start<strong>in</strong>g po<strong>in</strong>t for simple <strong>wxPython</strong> programs.”””<br />
import wx<br />
class Frame(wx.Frame):<br />
pass<br />
class App(wx.App):<br />
def OnInit(self):<br />
self.frame = Frame(parent=None, id=-1, title=’Spare’)<br />
self.frame.Show()<br />
self.SetTopW<strong>in</strong>dow(self.frame)<br />
return True<br />
if __name__ == ’__ma<strong>in</strong>__’:<br />
app = App()<br />
app.Ma<strong>in</strong>Loop()<br />
PyCrustPyWrap<br />
L<strong>in</strong>ux<br />
$ pywrap spare.py<br />
92 / 565
w<strong>in</strong>dows<br />
F:\>python pywrap.py spare.py<br />
PyWrapPyWrap<br />
wx.AppPyWrap<br />
shellwx.py.crust.CrustFramePyCrust<br />
<strong>wxPython</strong><br />
PyWrap4.3<br />
<br />
4.3<br />
“””PyWrap is a command l<strong>in</strong>e utility that runs a python<br />
program with additional runtime tools, such as PyCrust.”””<br />
__author__ = ”Patrick K. O’Brien ”<br />
__cvsid__ = ”$Id: PyCrust.txt,v 1.15 2005/03/29 23:39:27 rob<strong>in</strong>d Exp $”<br />
__revision__ = ”$Revision: 1.15 $”[11:-2]<br />
import os<br />
import sys<br />
import wx<br />
from wx.py.crust import CrustFrame<br />
def wrap(app):<br />
wx.InitAllImageHandlers()<br />
frame = CrustFrame()<br />
frame.SetSize((750, 525))<br />
frame.Show(True)<br />
frame.shell.<strong>in</strong>terp.locals[‘app’] = app<br />
app.Ma<strong>in</strong>Loop()<br />
def ma<strong>in</strong>(modulename=None):<br />
sys.path.<strong>in</strong>sert(0, os.curdir)<br />
if not modulename:<br />
if len(sys.argv) < 2:<br />
pr<strong>in</strong>t ”Please specify a module name.”<br />
93 / 565
aise SystemExit<br />
modulename = sys.argv[1]<br />
if modulename.endswith(‘.py’):<br />
modulename = modulename[:-3]<br />
module = __import__(modulename)<br />
# F<strong>in</strong>d the App class.<br />
App = None<br />
d = module.__dict__<br />
for item <strong>in</strong> d.keys():<br />
try:<br />
if issubclass(d[item], wx.App):<br />
App = d[item]<br />
except (NameError, TypeError):<br />
pass<br />
if App is None:<br />
pr<strong>in</strong>t ”No App class was found.”<br />
raise SystemExit<br />
app = App()<br />
wrap(app)<br />
if __name__ == ’__ma<strong>in</strong>__’:<br />
ma<strong>in</strong>()<br />
PyWrapspare(frame)PyCrust<br />
<br />
PyCrust <strong>in</strong> action<br />
PyCrust shellspare.py<br />
4.10wx<br />
<br />
>>> import wx<br />
>>> app.frame.panel = wx.Panel(parent=app.frame)<br />
>>> app.frame.panel.SetBackgroundColour(‘White’)<br />
True<br />
>>><br />
94 / 565
4.10<br />
<br />
<br />
<br />
>>> app.frame.panel.Refresh()<br />
<strong>wxPython</strong><br />
<br />
<br />
>>> app.frame.statusbar = app.frame.CreateStatusBar(number=3)<br />
95 / 565
app.frame.statusbar.SetStatusText(“Left”, 0)<br />
>>> app.frame.statusbar.SetStatusText(“Center”, 1)<br />
>>> app.frame.statusbar.SetStatusText(“Right”, 2)<br />
<br />
<br />
<br />
>>> app.frame.menubar = wx.MenuBar()<br />
>>> menu = wx.Menu()<br />
>>> app.frame.menubar.Append(menu, ”Primary”)<br />
True<br />
>>> app.frame.SetMenuBar(app.frame.menubar)<br />
>>> menu.Append(wx.NewId(), ”One”, ”First menu item”)<br />
<br />
>>> menu.Append(wx.NewId(), ”Two”, ”Second menu item”)<br />
<br />
>>><br />
PyCrust shell<strong>wxPython</strong><br />
<br />
<br />
<strong>wxPython</strong><br />
<br />
PyCrustPy<br />
<br />
4.5 Py<br />
PyCrustPyPython<br />
shell.py,crust.py,<strong>in</strong>trospect.py<strong>in</strong>terpreter.pyPyCrust<br />
<br />
PyCrustPyPyShell<br />
PyAlaMode<br />
Py<br />
96 / 565
<strong>wxPython</strong> shell<br />
<br />
Py<br />
Py<br />
GUIPyCrust,PyShell,PyAlaModePyAlaCarte<br />
<br />
4.5.1 GUI<br />
4.3<br />
PyAlaCarte<br />
PyAlaModenotebook<br />
PyCrust<br />
PyCrust<strong>wxPython</strong> shellnotebooknotebook<br />
<br />
PyFill<strong>in</strong>g<br />
<br />
PyShell<strong>wxPython</strong> shellPyCrustnotebook<br />
PyShell<strong>wxPython</strong> shellPyCrust<br />
PyWrapPyCrust<br />
PyCrust shell<br />
4.5.2 <br />
<br />
Py4.4Py<br />
<br />
buffer<br />
crustPyCrustGUI<br />
dispatcher<br />
documentdocumentDocument<br />
documentread()write()<br />
BufferDocument<br />
editorPyAlaCartePyAlaModeGUI<br />
editw<strong>in</strong>doweditw<strong>in</strong>dowEditW<strong>in</strong>dow<br />
wx.stc.StyledTextCtrl (STC)PySTC<br />
Python shell,<br />
<br />
97 / 565
fill<strong>in</strong>gGUIGUI<br />
<br />
frameframeFrameFramePyframes<br />
<br />
imagesimagesPy<br />
<strong>in</strong>terpreterInterpreter<br />
<strong>in</strong>trospect<br />
pseudoInterpreter<br />
std<strong>in</strong>,stdout,stderr<br />
shellGUIGUIPyCrust,PyShell<br />
PyAlaModePython shell<br />
versionVERSIONVERSIONPy<br />
<br />
<br />
<br />
bufferBufferbuffer<br />
new(), open(), hasChanged(), save(),saveAs()buffer<br />
DocumentDocumentdocument<br />
EditorEditoreditor<br />
buffer<br />
BufferbufferPython<br />
bufferPython<br />
buffer<br />
bufferupdateNamespace()4.4<br />
updateNamespace()<br />
4.4<br />
def updateNamespace(self):<br />
”””Update the namespace for autocompletion and calltips.<br />
Return True if updated, False if there was an error.”””<br />
if not self.<strong>in</strong>terp or not hasattr(self.editor, ’getText’):<br />
return False<br />
syspath = sys.path<br />
sys.path = self.syspath<br />
text = self.editor.getText()<br />
text = text.replace(‘\r\n’, ’\n’)<br />
98 / 565
text = text.replace(‘\r’, ’\n’)<br />
name = self.modulename or self.name<br />
module = imp.new_module(name)<br />
newspace = module.__dict__.copy()<br />
try:<br />
try:<br />
code = compile(text, name, ’exec’)<br />
except:<br />
raise<br />
try:<br />
exec code <strong>in</strong> newspace<br />
except:<br />
raise<br />
else:<br />
# No problems, so update the namespace.<br />
self.<strong>in</strong>terp.locals.clear()<br />
self.<strong>in</strong>terp.locals.update(newspace)<br />
return True<br />
f<strong>in</strong>ally:<br />
sys.path = syspath<br />
for m <strong>in</strong> sys.modules.keys():<br />
if m not <strong>in</strong> self.modules:<br />
del sys.modules[m]<br />
Pythoncompile<br />
execnewspace<br />
<br />
buffer<br />
99 / 565
crust6GUIPyCrust<br />
CrustFramewx.Frame4.3<br />
PyWrapCrustFramePyCrust<br />
<br />
4.5<br />
4.5<br />
Crustwx.SplitterW<strong>in</strong>dowshellnotebook<br />
DisplayPretty Pr<strong>in</strong>t<br />
Calltipshell<br />
SessionList<strong>in</strong>g<br />
DispatcherList<strong>in</strong>g<br />
CrustFrameCrust<br />
GUI<strong>wxPython</strong><br />
<br />
<br />
dispatcher<br />
<br />
<br />
dispatcher<br />
dispatcher<br />
4.5dispatcherPy<br />
PyCrustPyShell<br />
PyCrustnotebook<br />
<br />
dispatcher<br />
4.5 dispatcher<br />
def push(self, command):<br />
”””Send command to the <strong>in</strong>terpreter to be executed.<br />
Because this may be called recursively, we append a new list<br />
onto the commandBuffer list and then append commands <strong>in</strong>to<br />
that. If the passed <strong>in</strong> command is part of a multi-l<strong>in</strong>e<br />
100 / 565
command we keep append<strong>in</strong>g the pieces to the last list <strong>in</strong><br />
commandBuffer until we have a complete command. If not, we<br />
delete that last list.”””<br />
command = str(command) # In case the command is unicode.<br />
if not self.more:<br />
try: del self.commandBuffer[-1]<br />
except IndexError: pass<br />
if not self.more: self.commandBuffer.append([])<br />
self.commandBuffer[-1].append(command)<br />
source = ’\n’.jo<strong>in</strong>(self.commandBuffer[-1])<br />
more = self.more = self.runsource(source)<br />
dispatcher.send(signal=’Interpreter.push’, sender=self,<br />
command=command, more=more, source=source)<br />
return more<br />
crustfill<strong>in</strong>gdispatcher,<br />
4.6PyCrustSession<br />
SessionList<strong>in</strong>g<br />
4.6 PyCrust session<br />
class SessionList<strong>in</strong>g(wx.TextCtrl):<br />
”””Text control conta<strong>in</strong><strong>in</strong>g all commands for session.”””<br />
def __<strong>in</strong>it__(self, parent=None, id=-1):<br />
style = (wx.TE_MULTILINE | wx.TE_READONLY |<br />
wx.TE_RICH2 | wx.TE_DONTWRAP)<br />
wx.TextCtrl.__<strong>in</strong>it__(self, parent, id, style=style)<br />
dispatcher.connect(receiver=self.push,<br />
signal=’Interpreter.push’)<br />
def push(self, command, more):<br />
”””Receiver for Interpreter.push signal.”””<br />
if command and not more:<br />
self.SetInsertionPo<strong>in</strong>tEnd()<br />
start, end = self.GetSelection()<br />
if start != end:<br />
self.SetSelection(0, 0)<br />
self.AppendText(command + ’\n’)<br />
101 / 565
SessionList<strong>in</strong>gpush()<br />
sendersourcedispatcher<br />
<br />
editorPyAlaCartePyAlaModeGUI<br />
Python<br />
4.6<br />
<br />
4.6 editor<br />
EditerFramePyAlaCarteEditerFrame<br />
frameFrame<br />
EditorNotebookFrameEditerFramenotebook<br />
EditerFramePyAlaModeframe<br />
EditorNotebookEditorNotebookFrame<br />
<br />
EditorbufferEditW<strong>in</strong>dow<br />
EditW<strong>in</strong>dowStyledTextCtrl<br />
fi<br />
fill<strong>in</strong>g<br />
GUI<br />
fill<strong>in</strong>g4.7<br />
4.7<br />
Fill<strong>in</strong>gTreewx.TreeCtrlFill<strong>in</strong>gTree<br />
Fill<strong>in</strong>gTexteditw<strong>in</strong>dow.EditW<strong>in</strong>dowFill<strong>in</strong>gTree<br />
<br />
Fill<strong>in</strong>gwx.SplitterW<strong>in</strong>dowFill<strong>in</strong>gTree<br />
Fill<strong>in</strong>gText<br />
Fill<strong>in</strong>gFrameFill<strong>in</strong>gfill<strong>in</strong>g<br />
Fill<strong>in</strong>gFrame<br />
Python<br />
Python<br />
102 / 565
<strong>in</strong>terpreterInterpreterPythoncode<br />
Interactive-InterpreterPythonInterpreter<br />
<br />
“.”<br />
Interpreter<br />
PyCrust shell<strong>in</strong>terpreter<br />
PyCrust<br />
<br />
<strong>in</strong>trospectInterpreterFill<strong>in</strong>gTree<br />
wx.py.<strong>in</strong>trospect<br />
<br />
>>> import wx<br />
>>> L = [1, 2, 3]<br />
>>> wx.py.<strong>in</strong>trospect.getAttributeNames(L, <strong>in</strong>cludeDouble=False)<br />
[‘append’, ’count’, ’extend’, ’<strong>in</strong>dex’, ’<strong>in</strong>sert’, ’pop’,<br />
‘remove’, ’reverse’, ’sort’]<br />
>>><br />
getAttributeNames()Fill<strong>in</strong>gTree<br />
PythonLib/sitepackages/wx/py/teststest_<strong>in</strong>trospect.py<br />
<br />
shellPyCrust, PyShell, PyAlaModePython shell<br />
GUI4.8ShellFrame,<br />
frame.FrameShellShellPython<br />
<br />
4.8 shell<br />
ShellPython shellwx.stc.StyleTextCtrlShelleditw<strong>in</strong>dow.EditW<strong>in</strong>dow<br />
Python shell<br />
ShellFacadeshell<br />
shell<br />
103 / 565
ShellFrameShell<br />
ShellFacadePyCrustshellshell<br />
PyCrustPyShellShell<br />
Python shellshellshellabout()<br />
<br />
>>> shell.about()<br />
Author: ”Patrick K. O’Brien ”<br />
Py Version: 0.9.4<br />
Py Shell Revision: 1.7<br />
Py Interpreter Revision: 1.5<br />
Python Version: 2.3.3<br />
<strong>wxPython</strong> Version: 2.4.1.0p7<br />
Platform: l<strong>in</strong>ux2<br />
>>><br />
ShellStyledTextCtrl600<br />
shellShellFacadeshell<br />
shellshell<br />
25<br />
4.6 <strong>wxPython</strong>Py<br />
PyCrust<br />
shell<br />
<br />
<br />
<br />
2<br />
shell<br />
fill<strong>in</strong>gfill<strong>in</strong>g<br />
4.11<br />
104 / 565
4.11<br />
4.7<br />
<br />
105 / 565
4.7<br />
#!/usr/b<strong>in</strong>/env python<br />
import wx<br />
#1 <br />
from wx.py.shell import ShellFrame<br />
from wx.py.fill<strong>in</strong>g import Fill<strong>in</strong>gFrame<br />
import images<br />
class ToolbarFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self, parent, id):<br />
wx.Frame.__<strong>in</strong>it__(self, parent, id, ’Toolbars’,<br />
size=(300, 200))<br />
panel = wx.Panel(self, -1)<br />
panel.SetBackgroundColour(‘White’)<br />
statusBar = self.CreateStatusBar()<br />
toolbar = self.CreateToolBar()<br />
toolbar.AddSimpleTool(wx.NewId(), images.getNewBitmap(),<br />
”New”, ”Long help for ’New’”)<br />
toolbar.Realize()<br />
menuBar = wx.MenuBar()<br />
menu1 = wx.Menu()<br />
menuBar.Append(menu1, ”&File”)<br />
menu2 = wx.Menu()<br />
menu2.Append(wx.NewId(), ”&Copy”, ”Copy <strong>in</strong> status bar”)<br />
menu2.Append(wx.NewId(), ”C&ut”, ””)<br />
menu2.Append(wx.NewId(), ”Paste”, ””)<br />
menu2.AppendSeparator()<br />
menu2.Append(wx.NewId(), ”&Options...”, ”Display Options”)<br />
menuBar.Append(menu2, ”&Edit”)<br />
#2 Debug<br />
menu3 = wx.Menu()<br />
shell = menu3.Append(-1, ”&<strong>wxPython</strong> shell”,<br />
”Open <strong>wxPython</strong> shell frame”)<br />
fill<strong>in</strong>g = menu3.Append(-1, ”&Namespace viewer”,<br />
”Open namespace viewer frame”)<br />
menuBar.Append(menu3, ”&Debug”)<br />
#3 <br />
106 / 565
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnShell, shell)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnFill<strong>in</strong>g, fill<strong>in</strong>g)<br />
self.SetMenuBar(menuBar)<br />
def OnCloseMe(self, event):<br />
self.Close(True)<br />
def OnCloseW<strong>in</strong>dow(self, event):<br />
self.Destroy()<br />
#4 OnShellOnFill<strong>in</strong>g<br />
def OnShell(self, event):<br />
frame = ShellFrame(parent=self)<br />
frame.Show()<br />
def OnFill<strong>in</strong>g(self, event):<br />
frame = Fill<strong>in</strong>gFrame(parent=self)<br />
frame.Show()<br />
if __name__ == ’__ma<strong>in</strong>__’:<br />
app = wx.PySimpleApp()<br />
app.frame = ToolbarFrame(parent=None, id=-1)<br />
app.frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
<br />
#1 ShellFrameFill<strong>in</strong>gFrame<br />
#2 Debug<br />
#3 wx.EVT_MENU()<br />
<br />
#4 DebugPython shellshell<br />
shellfill<strong>in</strong>g<br />
<br />
107 / 565
4.7 <br />
1<strong>wxPython</strong>GUI<br />
<br />
PyCrust shell<br />
2PyCrustPython shell<br />
IDLE, Boa Constructor, PythonW<strong>in</strong>shell<br />
PyCrust<strong>wxPython</strong><strong>wxPython</strong><br />
PyCrust<br />
shell<br />
3PyCrust<strong>wxPython</strong><strong>wxPython</strong><br />
PyCrust<br />
<br />
4Py<br />
shell<br />
5PyCrust<strong>wxPython</strong><br />
<br />
<strong>wxPython</strong><br />
GUI<br />
108 / 565
5<br />
GUI<br />
UI<br />
<br />
UIMVCModełView/Controller<br />
<br />
<strong>wxPython</strong><br />
<strong>wxPython</strong>UI<br />
<br />
<br />
5.1 <br />
<br />
<br />
<br />
<br />
<br />
<br />
UI<br />
5.1<br />
<br />
<br />
5.1 <br />
<br />
<br />
<br />
<br />
23<br />
<br />
<br />
<br />
<br />
PythonPython<br />
<br />
Python<br />
109 / 565
Python<br />
<br />
5.1.1 <br />
<br />
5.1Access<br />
5.1<br />
<br />
5.1<br />
5.1 5.1<br />
#!/usr/b<strong>in</strong>/env python<br />
import wx<br />
class RefactorExample(wx.Frame):<br />
def __<strong>in</strong>it__(self, parent, id):<br />
wx.Frame.__<strong>in</strong>it__(self, parent, id, ’Refactor Example’,<br />
size=(340, 200))<br />
panel = wx.Panel(self, -1)<br />
panel.SetBackgroundColour(“White”)<br />
prevButton = wx.Button(panel, -1, ”>”, pos=(160, 0))<br />
110 / 565
self.B<strong>in</strong>d(wx.EVT_BUTTON, self.OnNext, nextButton)<br />
self.B<strong>in</strong>d(wx.EVT_CLOSE, self.OnCloseW<strong>in</strong>dow)<br />
menuBar = wx.MenuBar()<br />
menu1 = wx.Menu()<br />
openMenuItem = menu1.Append(-1, ”&Open”, ”Copy <strong>in</strong> status bar”)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnOpen, openMenuItem)<br />
quitMenuItem = menu1.Append(-1, ”&Quit”, ”Quit”)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnCloseW<strong>in</strong>dow, quitMenuItem)<br />
menuBar.Append(menu1, ”&File”)<br />
menu2 = wx.Menu()<br />
copyItem = menu2.Append(-1, ”&Copy”, ”Copy”)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnCopy, copyItem)<br />
cutItem = menu2.Append(-1, ”C&ut”, ”Cut”)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnCut, cutItem)<br />
pasteItem = menu2.Append(-1, ”Paste”, ”Paste”)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnPaste, pasteItem)<br />
menuBar.Append(menu2, ”&Edit”)<br />
self.SetMenuBar(menuBar)<br />
static = wx.StaticText(panel, wx.NewId(), ”First Name”,<br />
pos=(10, 50))<br />
static.SetBackgroundColour(“White”)<br />
text = wx.TextCtrl(panel, wx.NewId(), ””, size=(100, -1),<br />
pos=(80, 50))<br />
static2 = wx.StaticText(panel, wx.NewId(), ”Last Name”,<br />
pos=(10, 80))<br />
static2.SetBackgroundColour(“White”)<br />
text2 = wx.TextCtrl(panel, wx.NewId(), ””, size=(100, -1),<br />
pos=(80, 80))<br />
firstButton = wx.Button(panel, -1, ”FIRST”)<br />
self.B<strong>in</strong>d(wx.EVT_BUTTON, self.OnFirst, firstButton)<br />
menu2.AppendSeparator()<br />
optItem = menu2.Append(-1, ”&Options...”, ”Display Options”)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnOptions, optItem)<br />
lastButton = wx.Button(panel, -1, ”LAST”, pos=(240, 0))<br />
111 / 565
self.B<strong>in</strong>d(wx.EVT_BUTTON, self.OnLast, lastButton)<br />
# Just group<strong>in</strong>g the empty event handlers together<br />
def OnPrev(self, event): pass<br />
def OnNext(self, event): pass<br />
def OnLast(self, event): pass<br />
def OnFirst(self, event): pass<br />
def OnOpen(self, event): pass<br />
def OnCopy(self, event): pass<br />
def OnCut(self, event): pass<br />
def OnPaste(self, event): pass<br />
def OnOptions(self, event): pass<br />
def OnCloseW<strong>in</strong>dow(self, event):<br />
self.Destroy()<br />
if __name__ == ’__ma<strong>in</strong>__’:<br />
app = wx.PySimpleApp()<br />
frame = RefactorExample(parent=None, id=-1)<br />
frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
<br />
<br />
<br />
<br />
5.2<br />
5.2<br />
<br />
“” “<br />
”“/”<br />
(frame)<br />
<br />
112 / 565
5.1.2 <br />
5.2<br />
5.25.1<br />
5.2 <br />
def createButtonBar(self):<br />
firstButton = wx.Button(panel, -1, ”FIRST”)<br />
self.B<strong>in</strong>d(wx.EVT_BUTTON, self.OnFirst, firstButton)<br />
prevButton = wx.Button(panel, -1, ”>”, pos=(160, 0))<br />
self.B<strong>in</strong>d(wx.EVT_BUTTON, self.OnNext, nextButton)<br />
lastButton = wx.Button(panel, -1, ”LAST”, pos=(240, 0))<br />
self.B<strong>in</strong>d(wx.EVT_BUTTON, self.OnLast, lastButton)<br />
<br />
<br />
5.3<br />
5.3 <br />
def createButtonBar(self, panel):<br />
self.buildOneButton(panel, ”First”, self.OnFirst)<br />
self.buildOneButton(panel, ”>”, self.OnNext, (160, 0))<br />
self.buildOneButton(panel, ”Last”, self.OnLast, (240, 0))<br />
def buildOneButton(self, parent, label, handler, pos=(0,0)):<br />
button = wx.Button(parent, -1, label, pos)<br />
self.B<strong>in</strong>d(wx.EVT_BUTTON, handler, button)<br />
return button<br />
5.35.2<br />
ID<br />
ID<br />
113 / 565
uildOneButton()<br />
<br />
5.1.3 <br />
<br />
<br />
<br />
<br />
5.4<br />
<br />
<br />
5.4 <br />
def buttonData(self):<br />
return ((“First”, self.OnFirst),<br />
(“>”, self.OnNext),<br />
(“Last”, self.OnLast))<br />
def createButtonBar(self, panel, yPos=0):<br />
xPos = 0<br />
for eachLabel, eachHandler <strong>in</strong> self.buttonData():<br />
pos = (xPos, yPos)<br />
button = self.buildOneButton(panel, eachLabel, eachHandler, pos)<br />
xPos += button.GetSize().width<br />
def buildOneButton(self, parent, label, handler, pos=(0,0)):<br />
button = wx.Button(parent, -1, label, pos)<br />
self.B<strong>in</strong>d(wx.EVT_BUTTON, handler, button)<br />
return button<br />
5.4buttonData()<br />
<br />
<br />
114 / 565
createButtonBar()buttonData()<br />
x<br />
<br />
<br />
<br />
<br />
XML<br />
createButtonBar<br />
<br />
<br />
5.5<br />
5.5 <br />
#!/usr/b<strong>in</strong>/env python<br />
import wx<br />
class RefactorExample(wx.Frame):<br />
def __<strong>in</strong>it__(self, parent, id):<br />
wx.Frame.__<strong>in</strong>it__(self, parent, id, ’Refactor Example’,<br />
size=(340, 200))<br />
panel = wx.Panel(self, -1)<br />
panel.SetBackgroundColour(“White”)<br />
self.B<strong>in</strong>d(wx.EVT_CLOSE, self.OnCloseW<strong>in</strong>dow)<br />
self.createMenuBar() #<strong>in</strong>it<br />
self.createButtonBar(panel)<br />
self.createTextFields(panel)<br />
def menuData(self): #<br />
return ((“&File”,<br />
(“&Open”, ”Open <strong>in</strong> status bar”, self.OnOpen),<br />
(“&Quit”, ”Quit”, self.OnCloseW<strong>in</strong>dow)),<br />
(“&Edit”,<br />
(“&Copy”, ”Copy”, self.OnCopy),<br />
115 / 565
(“C&ut”, ”Cut”, self.OnCut),<br />
(“&Paste”, ”Paste”, self.OnPaste),<br />
(“”, ””, ””),<br />
(“&Options...”, ”DisplayOptions”, self.OnOptions)))<br />
#<br />
def createMenuBar(self):<br />
menuBar = wx.MenuBar()<br />
for eachMenuData <strong>in</strong> self.menuData():<br />
menuLabel = eachMenuData[0]<br />
menuItems = eachMenuData[1:]<br />
menuBar.Append(self.createMenu(menuItems), menuLabel)<br />
self.SetMenuBar(menuBar)<br />
def createMenu(self, menuData):<br />
menu = wx.Menu()<br />
for eachLabel, eachStatus, eachHandler <strong>in</strong> menuData:<br />
if not eachLabel:<br />
menu.AppendSeparator()<br />
cont<strong>in</strong>ue<br />
menuItem = menu.Append(-1, eachLabel, eachStatus)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, eachHandler, menuItem)<br />
return menu<br />
def buttonData(self): #<br />
return ((“First”, self.OnFirst),<br />
(“>”, self.OnNext),<br />
(“Last”, self.OnLast))<br />
#<br />
def createButtonBar(self, panel, yPos = 0):<br />
xPos = 0<br />
for eachLabel, eachHandler <strong>in</strong> self.buttonData():<br />
pos = (xPos, yPos)<br />
button = self.buildOneButton(panel, eachLabel,<br />
eachHandler, pos)<br />
xPos += button.GetSize().width<br />
def buildOneButton(self, parent, label, handler, pos=(0,0)):<br />
button = wx.Button(parent, -1, label, pos)<br />
self.B<strong>in</strong>d(wx.EVT_BUTTON, handler, button)<br />
116 / 565
eturn button<br />
def textFieldData(self): #<br />
return ((“First Name”, (10, 50)),<br />
(“Last Name”, (10, 80)))<br />
#<br />
def createTextFields(self, panel):<br />
for eachLabel, eachPos <strong>in</strong> self.textFieldData():<br />
self.createCaptionedText(panel, eachLabel, eachPos)<br />
def createCaptionedText(self, panel, label, pos):<br />
static = wx.StaticText(panel, wx.NewId(), label, pos)<br />
static.SetBackgroundColour(“White”)<br />
textPos = (pos[0] + 75, pos[1])<br />
wx.TextCtrl(panel, wx.NewId(), ””, size=(100, -1), pos=textPos)<br />
# <br />
def OnPrev(self, event): pass<br />
def OnNext(self, event): pass<br />
def OnLast(self, event): pass<br />
def OnFirst(self, event): pass<br />
def OnOpen(self, event): pass<br />
def OnCopy(self, event): pass<br />
def OnCut(self, event): pass<br />
def OnPaste(self, event): pass<br />
def OnOptions(self, event): pass<br />
def OnCloseW<strong>in</strong>dow(self, event):<br />
self.Destroy()<br />
if __name__ == ’__ma<strong>in</strong>__’:<br />
app = wx.PySimpleApp()<br />
frame = RefactorExample(parent=None, id=-1)<br />
frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
5.15.5——<br />
<br />
——<br />
<br />
117 / 565
5.5<br />
<br />
MVC<br />
<br />
5.2 (Model)(View)<br />
1970Smalltalk-80MVC<br />
<br />
GUIMVC<br />
<br />
5.2.1 MVC(Model-View-Controller)<br />
MVCModel<br />
View<br />
ControllerControllerModel<br />
view5.3<br />
<br />
5.3 MVC<br />
<br />
Model,<br />
(model)API<br />
View<br />
<strong>wxPython</strong>wx.W<strong>in</strong>dow(view)<br />
<br />
Controller<br />
<strong>wxPython</strong>wx.EvtHandler<br />
UIViewController<br />
Controller<br />
<strong>wxPython</strong><br />
wx.W<strong>in</strong>dowwx.EvtHandler<br />
118 / 565
ViewControllerwebView<br />
Controller<br />
5.2MVC<br />
Controller<br />
<strong>wxPython</strong>wx.EvtHandler<br />
ProcessEvent()MVC<br />
<br />
(model)<br />
<br />
(controller)<br />
(view)<br />
<strong>wxPython</strong><br />
<strong>wxPython</strong><br />
<br />
<br />
MVC<br />
MVC<br />
Model<br />
ViewControllerModel<br />
Model<strong>wxPython</strong><br />
<br />
ViewModelView<br />
ControllerViewModel<br />
Python<br />
119 / 565
ModelViewAPIModel<br />
<br />
<br />
<strong>wxPython</strong>Model<br />
wx.grid.PyGridTableBaseMVCgrid<br />
<br />
<br />
5.2.2 <strong>wxPython</strong>PyGridTableBase<br />
wx.grid.Grid<strong>wxPython</strong>5.3<br />
<br />
(grid)<br />
<br />
<br />
5.6<br />
1984<br />
5.6 <br />
import wx<br />
import wx.grid<br />
120 / 565
class SimpleGrid(wx.grid.Grid):<br />
def __<strong>in</strong>it__(self, parent):<br />
wx.grid.Grid.__<strong>in</strong>it__(self, parent, -1)<br />
self.CreateGrid(9, 2)<br />
self.SetColLabelValue(0, ”First”)<br />
self.SetColLabelValue(1, ”Last”)<br />
self.SetRowLabelValue(0, ”CF”)<br />
self.SetCellValue(0, 0, ”Bob”)<br />
self.SetCellValue(0, 1, ”Dernier”)<br />
self.SetRowLabelValue(1, ”2B”)<br />
self.SetCellValue(1, 0, ”Ryne”)<br />
self.SetCellValue(1, 1, ”Sandberg”)<br />
self.SetRowLabelValue(2, ”LF”)<br />
self.SetCellValue(2, 0, ”Gary”)<br />
self.SetCellValue(2, 1, ”Matthews”)<br />
self.SetRowLabelValue(3, ”1B”)<br />
self.SetCellValue(3, 0, ”Leon”)<br />
self.SetCellValue(3, 1, ”Durham”)<br />
self.SetRowLabelValue(4, ”RF”)<br />
self.SetCellValue(4, 0, ”Keith”)<br />
self.SetCellValue(4, 1, ”Moreland”)<br />
self.SetRowLabelValue(5, ”3B”)<br />
self.SetCellValue(5, 0, ”Ron”)<br />
self.SetCellValue(5, 1, ”Cey”)<br />
self.SetRowLabelValue(6, ”C”)<br />
self.SetCellValue(6, 0, ”Jody”)<br />
self.SetCellValue(6, 1, ”Davis”)<br />
self.SetRowLabelValue(7, ”SS”)<br />
self.SetCellValue(7, 0, ”Larry”)<br />
self.SetCellValue(7, 1, ”Bowa”)<br />
self.SetRowLabelValue(8, ”P”)<br />
self.SetCellValue(8, 0, ”Rick”)<br />
self.SetCellValue(8, 1, ”Sutcliffe”)<br />
class TestFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self, parent):<br />
wx.Frame.__<strong>in</strong>it__(self, parent, -1, ”A Grid”,<br />
size=(275, 275))<br />
grid = SimpleGrid(self)<br />
121 / 565
if __name__ == ’__ma<strong>in</strong>__’:<br />
app = wx.PySimpleApp()<br />
frame = TestFrame(None)<br />
frame.Show(True)<br />
app.Ma<strong>in</strong>Loop()<br />
5.6SimpleGrid<strong>wxPython</strong>wx.grid.Grid<br />
wx.grid.Grid<br />
SetRowLabelValue()SetColLabelValue()SetCellValue()<br />
5.35.6SetCellValue()<br />
<br />
<br />
set***<br />
<br />
<br />
<br />
wx.grid.PyGridTableBase<br />
PyC++Python<br />
PyEventPyGridTableBasewxWidgets C<br />
++(Python)<br />
PyGridTableBase<br />
PyGridTableBase<br />
<br />
<br />
wx.grid.PyGridTableBase<br />
PyGridTableBase<br />
5.4<br />
5.4 wx.grid.PyGridTableBase<br />
GetNumberRows()grid<br />
GetNumberCols()grid<br />
IsEmptyCell(row, col)(row,col)True<br />
GetValue(row, col)(row,col)<br />
122 / 565
SetValue(row, col,value)(row,col)<br />
pass<br />
(table)(grid)SetTable()grid<br />
gridgrid<br />
grid<br />
<br />
PyGridTableBase<br />
PyGridTableBasePyGridTableBase<br />
<br />
<br />
<br />
<strong>wxPython</strong><br />
<br />
<br />
PyGridTableBase<br />
<br />
PyGridTableBase<br />
Python5.7<br />
<br />
5.7 PyGridTableBase<br />
import wx<br />
import wx.grid<br />
class L<strong>in</strong>eupTable(wx.grid.PyGridTableBase):<br />
data = ((“CF”, ”Bob”, ”Dernier”), (“2B”, ”Ryne”, ”Sandberg”),<br />
(“LF”, ”Gary”, ”Matthews”), (“1B”, ”Leon”, ”Durham”),<br />
(“RF”, ”Keith”, ”Moreland”), (“3B”, ”Ron”, ”Cey”),<br />
(“C”, ”Jody”, ”Davis”), (“SS”, ”Larry”, ”Bowa”),<br />
(“P”, ”Rick”, ”Sutcliffe”))<br />
colLabels = (“Last”, ”First”)<br />
123 / 565
def __<strong>in</strong>it__(self):<br />
wx.grid.PyGridTableBase.__<strong>in</strong>it__(self)<br />
def GetNumberRows(self):<br />
return len(self.data)<br />
def GetNumberCols(self):<br />
return len(self.data[0]) - 1<br />
def GetColLabelValue(self, col):<br />
return self.colLabels[col]<br />
def GetRowLabelValue(self, row):<br />
return self.data[row][0]<br />
def IsEmptyCell(self, row, col):<br />
return False<br />
def GetValue(self, row, col):<br />
return self.data[row][col + 1]<br />
def SetValue(self, row, col, value):<br />
pass<br />
class SimpleGrid(wx.grid.Grid):<br />
def __<strong>in</strong>it__(self, parent):<br />
wx.grid.Grid.__<strong>in</strong>it__(self, parent, -1)<br />
self.SetTable(L<strong>in</strong>eupTable()) #<br />
class TestFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self, parent):<br />
wx.Frame.__<strong>in</strong>it__(self, parent, -1, ”A Grid”,<br />
size=(275, 275))<br />
grid = SimpleGrid(self)<br />
if __name__ == ’__ma<strong>in</strong>__’:<br />
app = wx.PySimpleApp()<br />
frame = TestFrame(None)<br />
frame.Show(True)<br />
app.Ma<strong>in</strong>Loop()<br />
124 / 565
5.7PyGridTableBase<br />
GetColLabelValue()GetRowLabelValue()<br />
(table)<br />
<br />
<br />
<br />
<br />
Python<br />
5.8<br />
5.8 <br />
import wx<br />
import wx.grid<br />
class GenericTable(wx.grid.PyGridTableBase):<br />
def __<strong>in</strong>it__(self, data, rowLabels=None, colLabels=None):<br />
wx.grid.PyGridTableBase.__<strong>in</strong>it__(self)<br />
self.data = data<br />
self.rowLabels = rowLabels<br />
self.colLabels = colLabels<br />
def GetNumberRows(self):<br />
return len(self.data)<br />
def GetNumberCols(self):<br />
return len(self.data[0])<br />
def GetColLabelValue(self, col):<br />
if self.colLabels:<br />
return self.colLabels[col]<br />
def GetRowLabelValue(self, row):<br />
if self.rowLabels:<br />
return self.rowLabels[row]<br />
125 / 565
def IsEmptyCell(self, row, col):<br />
return False<br />
def GetValue(self, row, col):<br />
return self.data[row][col]<br />
def SetValue(self, row, col, value):<br />
pass<br />
GenericTable<br />
<strong>wxPython</strong><br />
5.9<br />
5.9 <br />
import wx<br />
import wx.grid<br />
import generictable<br />
data = ((“Bob”, ”Dernier”), (“Ryne”, ”Sandberg”),<br />
(“Gary”, ”Matthews”), (“Leon”, ”Durham”),<br />
(“Keith”, ”Moreland”), (“Ron”, ”Cey”),<br />
(“Jody”, ”Davis”), (“Larry”, ”Bowa”),<br />
(“Rick”, ”Sutcliffe”))<br />
colLabels = (“Last”, ”First”)<br />
rowLabels = (“CF”, ”2B”, ”LF”, ”1B”, ”RF”, ”3B”, ”C”, ”SS”, ”P”)<br />
class SimpleGrid(wx.grid.Grid):<br />
def __<strong>in</strong>it__(self, parent):<br />
wx.grid.Grid.__<strong>in</strong>it__(self, parent, -1)<br />
tableBase = generictable.GenericTable(data, rowLabels,<br />
colLabels)<br />
self.SetTable(tableBase)<br />
class TestFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self, parent):<br />
wx.Frame.__<strong>in</strong>it__(self, parent, -1, ”A Grid”,<br />
126 / 565
size=(275, 275))<br />
grid = SimpleGrid(self)<br />
if __name__ == ’__ma<strong>in</strong>__’:<br />
app = wx.PySimpleApp()<br />
frame = TestFrame(None)<br />
frame.Show(True)<br />
app.Ma<strong>in</strong>Loop()<br />
<br />
PyGridTableBase<br />
<br />
PyGridTableBasePython<br />
getattr()<br />
<strong>wxPython</strong><br />
grid<br />
SetTable()grid<br />
PyGridTableBase<br />
<br />
<br />
5.10PyGridTableBase<br />
<br />
5.10 <br />
import wx<br />
import wx.grid<br />
class L<strong>in</strong>eupEntry:<br />
def __<strong>in</strong>it__(self, pos, first, last):<br />
self.pos = pos<br />
self.first = first<br />
self.last = last<br />
class L<strong>in</strong>eupTable(wx.grid.PyGridTableBase):<br />
colLabels = (“First”, ”Last”) # <br />
127 / 565
colAttrs = (“first”, ”last”) #1 <br />
def __<strong>in</strong>it__(self, entries): #2 <br />
wx.grid.PyGridTableBase.__<strong>in</strong>it__(self)<br />
self.entries = entries<br />
def GetNumberRows(self):<br />
return len(self.entries)<br />
def GetNumberCols(self):<br />
return 2<br />
def GetColLabelValue(self, col):<br />
return self.colLabels[col] #<br />
def GetRowLabelValue(self, col):<br />
return self.entries[row].pos #3 <br />
def IsEmptyCell(self, row, col):<br />
return False<br />
def GetValue(self, row, col):<br />
entry = self.entries[row]<br />
return getattr(entry, self.colAttrs[col]) #4 <br />
def SetValue(self, row, col, value):<br />
pass<br />
<br />
#1<br />
#2L<strong>in</strong>eupEntry<br />
<br />
#3pos<br />
#4#1<br />
getattr()<br />
<br />
128 / 565
.Python<br />
<br />
grid<strong>wxPython</strong><br />
<strong>wxPython</strong><br />
5.2.3 <br />
<br />
<br />
<br />
<br />
<br />
<br />
5.10<br />
5.11<br />
——<br />
PyGridTableBase(grid)<br />
<br />
5.11 <br />
class AbstractModel(object):<br />
def __<strong>in</strong>it__(self):<br />
self.listeners = []<br />
def addListener(self, listenerFunc):<br />
self.listeners.append(listenerFunc)<br />
def removeListener(self, listenerFunc):<br />
self.listeners.remove(listenerFunc)<br />
def update(self):<br />
for eachFunc <strong>in</strong> self.listeners:<br />
eachFunc(self)<br />
listenerself<br />
eachFunc(self)——self<br />
129 / 565
listenterAbstractModelPython<br />
objectPythonPython2.2<br />
5.4<br />
<br />
<br />
MVC<br />
5.12<br />
<br />
5.12<br />
#!/usr/b<strong>in</strong>/env python<br />
import wx<br />
import abstractmodel<br />
class SimpleName(abstractmodel.AbstractModel):<br />
def __<strong>in</strong>it__(self, first=””, last=””):<br />
abstractmodel.AbstractModel.__<strong>in</strong>it__(self)<br />
self.set(first, last)<br />
def set(self, first, last):<br />
self.first = first<br />
130 / 565
self.last = last<br />
self.update() #1 <br />
class ModelExample(wx.Frame):<br />
def __<strong>in</strong>it__(self, parent, id):<br />
wx.Frame.__<strong>in</strong>it__(self, parent, id, ’Fl<strong>in</strong>tstones’,<br />
size=(340, 200))<br />
panel = wx.Panel(self)<br />
panel.SetBackgroundColour(“White”)<br />
self.B<strong>in</strong>d(wx.EVT_CLOSE, self.OnCloseW<strong>in</strong>dow)<br />
self.textFields = {}<br />
self.createTextFields(panel)<br />
#-------------------------------<br />
#2 <br />
self.model = SimpleName()<br />
self.model.addListener(self.OnUpdate)<br />
#-------------------------------<br />
self.createButtonBar(panel)<br />
def buttonData(self):<br />
return ((“Fredify”, self.OnFred),<br />
(“Wilmafy”, self.OnWilma),<br />
(“Barnify”, self.OnBarney),<br />
(“Bettify”, self.OnBetty))<br />
def createButtonBar(self, panel, yPos = 0):<br />
xPos = 0<br />
for eachLabel, eachHandler <strong>in</strong> self.buttonData():<br />
pos = (xPos, yPos)<br />
button = self.buildOneButton(panel, eachLabel, eachHandler, pos)<br />
xPos += button.GetSize().width<br />
def buildOneButton(self, parent, label, handler, pos=(0,0)):<br />
button = wx.Button(parent, -1, label, pos)<br />
self.B<strong>in</strong>d(wx.EVT_BUTTON, handler, button)<br />
return button<br />
def textFieldData(self):<br />
return ((“First Name”, (10, 50)),<br />
131 / 565
(“Last Name”, (10, 80)))<br />
def createTextFields(self, panel):<br />
for eachLabel, eachPos <strong>in</strong> self.textFieldData():<br />
self.createCaptionedText(panel, eachLabel, eachPos)<br />
def createCaptionedText(self, panel, label, pos):<br />
static = wx.StaticText(panel, wx.NewId(), label, pos)<br />
static.SetBackgroundColour(“White”)<br />
textPos = (pos[0] + 75, pos[1])<br />
self.textFields[label] = wx.TextCtrl(panel, wx.NewId(),<br />
””, size=(100, -1), pos=textPos,<br />
style=wx.TE_READONLY)<br />
def OnUpdate(self, model): #3 <br />
self.textFields[“First Name”].SetValue(model.first)<br />
self.textFields[“Last Name”].SetValue(model.last)<br />
#-------------------------------------------<br />
#4 <br />
def OnFred(self, event):<br />
self.model.set(“Fred”, ”Fl<strong>in</strong>tstone”)<br />
def OnBarney(self, event):<br />
self.model.set(“Barney”, ”Rubble”)<br />
def OnWilma(self, event):<br />
self.model.set(“Wilma”, ”Fl<strong>in</strong>tstone”)<br />
def OnBetty(self, event):<br />
self.model.set(“Betty”, ”Rubble”)<br />
#---------------------------------------------<br />
def OnCloseW<strong>in</strong>dow(self, event):<br />
self.Destroy()<br />
if __name__ == ’__ma<strong>in</strong>__’:<br />
app = wx.PySimpleApp()<br />
frame = ModelExample(parent=None, id=-1)<br />
frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
132 / 565
#1<br />
#2OnUpdate()<br />
listenerOnUpdate()<br />
#3OnUpdate()<br />
self.modelmodel<br />
<br />
<br />
#4<br />
<br />
<br />
<br />
Python<br />
<br />
<br />
AbstractModel5.10<br />
<br />
<strong>wxPython</strong>MVC<br />
wx.lib.pubsub<br />
AbstractModelPublisher<br />
wx.lib.evtmgr.eventManager<br />
pubsub<br />
<br />
5.3 GUI<br />
MVC“”<br />
<br />
MVC<br />
<br />
<br />
<br />
133 / 565
UI<br />
<br />
<br />
<strong>wxPython</strong><br />
<br />
5.3.1 unittest<br />
<br />
2.1Pythonunittestunittest<br />
PyUnithttp://pyunit.sourceforge.net/PyUnit<br />
Test,TestCase,TestSuite5.5<br />
5.5<br />
TestPyUnittest<br />
<br />
<br />
TestCase<br />
PyUnitTestCase<br />
TestCase<br />
assertEqual<br />
TestSuitetestTestCase<br />
PyUnitTestSuite<br />
PyUnitsuccess, failure, <br />
errorsuccess<br />
<br />
Failureerrorfailurefalse<br />
error<br />
Pythonfailure<br />
error<br />
<br />
134 / 565
5.3.2 unittest<br />
5.13unittest5.12<br />
<br />
5.13 <br />
import unittest<br />
import modelExample<br />
import wx<br />
class TestExample(unittest.TestCase): #1 TestCase<br />
def setUp(self): #2 <br />
self.app = wx.PySimpleApp()<br />
self.frame = modelExample.ModelExample(parent=None, id=-1)<br />
def tearDown(self): #3 <br />
self.frame.Destroy()<br />
def testModel(self): #4 (Test)<br />
self.frame.OnBarney(None)<br />
self.assertEqual(“Barney”, self.frame.model.first,<br />
msg=”First is wrong”) #5 <br />
self.assertEqual(“Rubble”, self.frame.model.last)<br />
def suite(): #6 TestSuite<br />
suite = unittest.makeSuite(TestExample, ’test’)<br />
return suite<br />
if __name__ == ’__ma<strong>in</strong>__’:<br />
unittest.ma<strong>in</strong>(defaultTest=’suite’) #7 <br />
<br />
#1unittest.TestCase<br />
<br />
135 / 565
#2 setUp()<br />
<br />
(frame)<br />
#3 tearDown()<br />
<br />
<br />
Destroy()wxWidgets<br />
<br />
#4 test#6<br />
OnBarney<br />
<br />
#5 assertEqual()<br />
assertEqual()<br />
PyUnitmsgmsg(msg<br />
<br />
#6 makeSuite()<br />
Python<br />
“”<br />
makeSuite()suite()<br />
<br />
#7 PyUnit<br />
suite<br />
GUIunittest.TextTestRunner<br />
unittest.ma<strong>in</strong><br />
PyUnit<br />
.<br />
----------------------------------------------------------------------<br />
Ran 1 test <strong>in</strong> 0.190s<br />
OK<br />
“.”<br />
“.”“F”“E”<br />
136 / 565
OKOK<br />
<br />
Python<br />
#5<br />
self.assertEqual(“Fife”, self.frame.model.first)<br />
F<br />
============================================================<br />
==========<br />
FAIL: testModel (__ma<strong>in</strong>__.TestExample)<br />
----------------------------------------------------------------------<br />
Traceback (most recent call last):<br />
File ”C:\wxPyBook\book\1\Bluepr<strong>in</strong>t\testExample.py”, l<strong>in</strong>e 18, <strong>in</strong> testModel<br />
self.assertEqual(“Fife”, self.frame.model.last)<br />
File ”c:\python23\lib\unittest.py”, l<strong>in</strong>e 302, <strong>in</strong> failUnlessEqual<br />
raise self.failureException, \<br />
AssertionError: ’Fife’ != ’Rubble’<br />
----------------------------------------------------------------------<br />
Ran 1 test <strong>in</strong> 0.070s<br />
FAILED (failures=1)<br />
“F”“testModel”18<br />
<br />
<br />
5.3.3 <br />
TextField<br />
<br />
<br />
5.14<br />
5.14 <br />
def testEvent(self):<br />
panel = self.frame.GetChildren()[0]<br />
for each <strong>in</strong> panel.GetChildren():<br />
137 / 565
if each.GetLabel() == ”Wilmafy”:<br />
wilma = each<br />
break<br />
event = wx.CommandEvent(wx.wxEVT_COMMAND_BUTTON_CLICKED, wil<br />
ma.GetId())<br />
wilma.GetEventHandler().ProcessEvent(event)<br />
self.assertEqual(“Wilma”, self.frame.model.first)<br />
self.assertEqual(“Fl<strong>in</strong>tstone”, self.frame.model.last)<br />
“Wilmafy”<br />
panel<br />
<br />
wx.CommandEvent<br />
wx.wxEVT_COMMAND_BUTTON_CLICKED<br />
EVT_BUTTON<br />
wx.pywilma.GetId()<br />
ID<strong>wxPython</strong><br />
ProcessEvent()<br />
firstlast“Wilma” “Fl<strong>in</strong>tstone”<br />
<br />
<br />
wx.Events<br />
<br />
<br />
<br />
5.4 <br />
1GUI<br />
<br />
2<br />
<br />
<br />
<br />
3<br />
MVC<strong>wxPython</strong>V(View)<br />
138 / 565
wx.W<strong>in</strong>dowC(Controller)wx.EvtHandler<br />
M(Model)<br />
4MVC<strong>wxPython</strong><br />
wx.grid.PyGridTableBasewx.grid.Grid<br />
<br />
<br />
5MVC<br />
(view)<strong>wxPython</strong><br />
<br />
6Python<br />
unittestGUI<br />
<strong>wxPython</strong><br />
<br />
<br />
<strong>wxPython</strong><br />
139 / 565
6<br />
<strong>wxPython</strong><br />
GUI<br />
<br />
<br />
<br />
<br />
<br />
<strong>wxPython</strong><br />
23<br />
<strong>wxPython</strong>/samples<br />
<br />
6.1<br />
6.1<br />
<br />
<br />
<br />
sizer<br />
140 / 565
6.1 <br />
GUI<br />
<strong>wxPython</strong><br />
<br />
6.1.1 <br />
device context<br />
<strong>wxPython</strong><br />
<br />
<strong>wxPython</strong>wx.DC<br />
wx.DC<br />
<br />
6.1wx.DC<strong>wxPython</strong><br />
<br />
<br />
wx.DC<strong>wxPython</strong><br />
wx.DC<br />
<br />
6.1<br />
wx.BufferedDC<br />
<br />
wx.BufferedPa<strong>in</strong>tDCwx.BufferedDCwx.Pa<strong>in</strong>tEvent<br />
<br />
wx.ClientDC<br />
wx.ClientDC<br />
wx.Pa<strong>in</strong>tEvent<br />
wx.MemoryDC<br />
wx.DC.Blit()<br />
141 / 565
wx.MetafileDCW<strong>in</strong>dowswx.MetafileDC<br />
<br />
wx.Pa<strong>in</strong>tDCwx.ClientDCwx.Pa<strong>in</strong>tEvent<br />
<br />
wx.PostScriptDCPostScript<br />
wx.Pr<strong>in</strong>terDCW<strong>in</strong>dows<br />
wx.ScreenDC<br />
<br />
wx.W<strong>in</strong>dowDC<br />
W<strong>in</strong>dows<br />
6.16.1<br />
<br />
6.1 SketchW<strong>in</strong>dow<br />
import wx<br />
class SketchW<strong>in</strong>dow(wx.W<strong>in</strong>dow):<br />
def __<strong>in</strong>it__(self, parent, ID):<br />
wx.W<strong>in</strong>dow.__<strong>in</strong>it__(self, parent, ID)<br />
self.SetBackgroundColour(“White”)<br />
self.color = ”Black”<br />
self.thickness = 1<br />
self.pen = wx.Pen(self.color, self.thickness, wx.SOLID)#1 wx.Pen<br />
<br />
self.l<strong>in</strong>es = []<br />
self.curL<strong>in</strong>e = []<br />
self.pos = (0, 0)<br />
self.InitBuffer()<br />
#2 <br />
self.B<strong>in</strong>d(wx.EVT_LEFT_DOWN, self.OnLeftDown)<br />
self.B<strong>in</strong>d(wx.EVT_LEFT_UP, self.OnLeftUp)<br />
self.B<strong>in</strong>d(wx.EVT_MOTION, self.OnMotion)<br />
self.B<strong>in</strong>d(wx.EVT_SIZE, self.OnSize)<br />
142 / 565
self.B<strong>in</strong>d(wx.EVT_IDLE, self.OnIdle)<br />
self.B<strong>in</strong>d(wx.EVT_PAINT, self.OnPa<strong>in</strong>t)<br />
def InitBuffer(self):<br />
size = self.GetClientSize()<br />
#3 <br />
self.buffer = wx.EmptyBitmap(size.width, size.height)<br />
dc = wx.BufferedDC(None, self.buffer)<br />
#4 <br />
dc.SetBackground(wx.Brush(self.GetBackgroundColour()))<br />
dc.Clear()<br />
self.DrawL<strong>in</strong>es(dc)<br />
self.reInitBuffer = False<br />
def GetL<strong>in</strong>esData(self):<br />
return self.l<strong>in</strong>es[:]<br />
def SetL<strong>in</strong>esData(self, l<strong>in</strong>es):<br />
self.l<strong>in</strong>es = l<strong>in</strong>es[:]<br />
self.InitBuffer()<br />
self.Refresh()<br />
def OnLeftDown(self, event):<br />
self.curL<strong>in</strong>e = []<br />
self.pos = event.GetPositionTuple()#5 <br />
self.CaptureMouse()#6 <br />
def OnLeftUp(self, event):<br />
if self.HasCapture():<br />
self.l<strong>in</strong>es.append((self.color,<br />
self.thickness,<br />
self.curL<strong>in</strong>e))<br />
self.curL<strong>in</strong>e = []<br />
self.ReleaseMouse()#7 <br />
def OnMotion(self, event):<br />
if event.Dragg<strong>in</strong>g() and event.LeftIsDown():#8 <br />
143 / 565
dc = wx.BufferedDC(wx.ClientDC(self), self.buffer)#9 <br />
<br />
self.drawMotion(dc, event)<br />
event.Skip()<br />
#10 <br />
def drawMotion(self, dc, event):<br />
dc.SetPen(self.pen)<br />
newPos = event.GetPositionTuple()<br />
coords = self.pos + newPos<br />
self.curL<strong>in</strong>e.append(coords)<br />
dc.DrawL<strong>in</strong>e(*coords)<br />
self.pos = newPos<br />
def OnSize(self, event):<br />
self.reInitBuffer = True #11 resize<br />
def OnIdle(self, event):#12 <br />
if self.reInitBuffer:<br />
self.InitBuffer()<br />
self.Refresh(False)<br />
def OnPa<strong>in</strong>t(self, event):<br />
dc = wx.BufferedPa<strong>in</strong>tDC(self, self.buffer)#13 pa<strong>in</strong>t<br />
#14 <br />
def DrawL<strong>in</strong>es(self, dc):<br />
for colour, thickness, l<strong>in</strong>e <strong>in</strong> self.l<strong>in</strong>es:<br />
pen = wx.Pen(colour, thickness, wx.SOLID)<br />
dc.SetPen(pen)<br />
for coords <strong>in</strong> l<strong>in</strong>e:<br />
dc.DrawL<strong>in</strong>e(*coords)<br />
def SetColor(self, color):<br />
self.color = color<br />
self.pen = wx.Pen(self.color, self.thickness, wx.SOLID)<br />
def SetThickness(self, num):<br />
self.thickness = num<br />
self.pen = wx.Pen(self.color, self.thickness, wx.SOLID)<br />
144 / 565
class SketchFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self, parent):<br />
wx.Frame.__<strong>in</strong>it__(self, parent, -1, ”Sketch Frame”,<br />
size=(800,600))<br />
self.sketch = SketchW<strong>in</strong>dow(self, -1)<br />
if __name__ == ’__ma<strong>in</strong>__’:<br />
app = wx.PySimpleApp()<br />
frame = SketchFrame(None)<br />
frame.Show(True)<br />
app.Ma<strong>in</strong>Loop()<br />
<br />
#1wx.Pen<br />
wx.SOLIDwx.DOT, wx.LONGDASH, wx.SHORTDASH<br />
#2<br />
<br />
<br />
#31<br />
(offscreen)2<br />
<br />
<br />
#4<br />
(dc.Clear())dc.Clear()wx.EVT_PAINT<br />
wx.Brush<br />
<br />
#5GetPositionTuple()<br />
Python<br />
#6CaptureMouse()<br />
<br />
ReleaseMouse()<br />
#7<br />
145 / 565
#7ReleaseMouse()CaptureMouse()<br />
<strong>wxPython</strong><br />
ReleaseMouse()<br />
CaptureMouse()ReleaseMouse()<br />
#8<br />
Dragg<strong>in</strong>g()LeftIsDown()wx.MouseEvent<br />
true<br />
#9wx.BufferedDC<br />
wx.ClientDC<br />
<br />
#10<br />
coordsself.posnewPos<br />
GetPositionTuple()OnMotion()<br />
self.curL<strong>in</strong>eDrawL<strong>in</strong>e()*coords<br />
coordsx1,y1,x2,y2DrawL<strong>in</strong>e()x1,y1,x2,y2<br />
(x1,y1)(x2,y2)<br />
#11Trueself.reInitBuffer<br />
<br />
#12<br />
True<br />
self.reInitBuffer<br />
<br />
#13wx.EVT_PAINT<br />
OnPa<strong>in</strong>t<br />
wx.Pa<strong>in</strong>tDC<br />
Pa<strong>in</strong>twx.Pa<strong>in</strong>tDCwx.ClientDC<br />
dc<br />
(blit)<br />
#14<br />
self.l<strong>in</strong>es<br />
<br />
146 / 565
wx.DC<br />
<br />
<br />
<br />
<br />
<strong>wxPython</strong>wx.BufferDC<br />
wx.ClientDCwx.BufferPa<strong>in</strong>tDCwx.Pa<strong>in</strong>tDC<br />
<br />
6.1#9wx.ClientDC<br />
wx.Bitmap6.1wx.EmptyBitmap<br />
wx.MemoryDC<br />
C++Blit()<br />
<strong>wxPython</strong><br />
(blit)<br />
6.1OnPa<strong>in</strong>tself.buffersketch<br />
<br />
wx.Pa<strong>in</strong>tDC()DC<br />
<br />
<br />
<br />
wx.Pa<strong>in</strong>tDC wx.ClientDC<br />
6.2wx.DC<br />
6.2 wx.DC<br />
Blit(xdest, ydest, width,height, source, xsrc,ysrc)<br />
xdest, ydest<br />
sourcexsrc,ysrc<br />
<br />
Clear()<br />
DrawArc(x1, y1, x2, y2,xc, yc)(x1, y1)(x2, y2)<br />
(xc, yc)<br />
DrawEllipticalArc()<br />
DrawBitmap(bitmap, x,y, transparent)wx.Bitmap(x, y)<br />
transparent<br />
147 / 565
DrawCircle(x, y, radius)<br />
DrawCircle(po<strong>in</strong>t, radius)<br />
DrawEllipse<br />
DrawIcon(icon, x, y)wx.Icon(x, y)<br />
DrawL<strong>in</strong>e(x1, y1, x2, y2)(x1, y1)(x2, y2)<br />
DrawL<strong>in</strong>es()wx.Po<strong>in</strong>tPython<br />
<br />
DrawPolygon(po<strong>in</strong>ts)wx.Po<strong>in</strong>tPython<br />
DrawL<strong>in</strong>es()<br />
xy<br />
DrawRectangle(x, y,width, height)(x, y)<br />
widthheight<br />
<br />
DrawText(text, x, y)(x, y)<br />
DrawRotatedText()GetTextExtent()<br />
FloodFill(x, y, color,style)(x, y)<br />
stylestylewx.FLOOD_SURFACE<br />
wx.FLOOD_BORDERcolor<br />
<br />
GetBackground()<br />
SetBackground(brush)wx.BrushClear()<br />
<br />
GetBrush()<br />
SetBrush(brush)wx.Brush<br />
<br />
GetFont()<br />
SetFont(font)(font)wx.Font<br />
GetPen()<br />
SetPen(pen)(pen)wx.Pen<br />
GetPixel(x, y)(x, y)wx.Colour<br />
GetSize()<br />
148 / 565
GetSizeTuple()wx.SizePython<br />
<br />
<br />
<br />
6.2 <br />
<br />
<br />
10<br />
6.2.1 <br />
<strong>wxPython</strong>CreateStatusBar()<br />
<br />
wx.StatusBar<br />
SetStatusBar()<br />
<br />
wx.StatusBar<br />
SetStatusText()6.26.1SketchFrame<br />
<br />
6.2 <br />
import wx<br />
from example1 import SketchW<strong>in</strong>dow<br />
class SketchFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self, parent):<br />
wx.Frame.__<strong>in</strong>it__(self, parent, -1, ”Sketch Frame”,<br />
size=(800,600))<br />
self.sketch = SketchW<strong>in</strong>dow(self, -1)<br />
self.sketch.B<strong>in</strong>d(wx.EVT_MOTION, self.OnSketchMotion)<br />
self.statusbar = self.CreateStatusBar()<br />
def OnSketchMotion(self, event):<br />
self.statusbar.SetStatusText(str(event.GetPositionTuple()))<br />
149 / 565
event.Skip()<br />
if __name__ == ’__ma<strong>in</strong>__’:<br />
app = wx.PySimpleApp()<br />
frame = SketchFrame(None)<br />
frame.Show(True)<br />
app.Ma<strong>in</strong>Loop()<br />
wx.EVT_MOTION<br />
<br />
Skip()OnMotion()<br />
<br />
SetFieldsCount()<br />
SetStatusText()<br />
0<br />
0<br />
<br />
<strong>wxPython</strong><br />
SetStatusWidth()Python<br />
<br />
<br />
<br />
statusbar.SetStatusWidth([-1, -2,-3])<br />
1:2:36.2<br />
6.2<br />
6.3<br />
6.2<br />
6.3 <br />
import wx<br />
from example1 import SketchW<strong>in</strong>dow<br />
150 / 565
class SketchFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self, parent):<br />
wx.Frame.__<strong>in</strong>it__(self, parent, -1, ”Sketch Frame”,<br />
size=(800,600))<br />
self.sketch = SketchW<strong>in</strong>dow(self, -1)<br />
self.sketch.B<strong>in</strong>d(wx.EVT_MOTION, self.OnSketchMotion)<br />
self.statusbar = self.CreateStatusBar()<br />
self.statusbar.SetFieldsCount(3)<br />
self.statusbar.SetStatusWidths([-1, -2, -3])<br />
def OnSketchMotion(self, event):<br />
self.statusbar.SetStatusText(“Pos: %s” %<br />
str(event.GetPositionTuple()), 0)<br />
self.statusbar.SetStatusText(“Current Pts: %s” %<br />
len(self.sketch.curL<strong>in</strong>e), 1)<br />
self.statusbar.SetStatusText(“L<strong>in</strong>e Count: %s” %<br />
len(self.sketch.l<strong>in</strong>es), 2)<br />
event.Skip()<br />
if __name__ == ’__ma<strong>in</strong>__’:<br />
app = wx.PySimpleApp()<br />
frame = SketchFrame(None)<br />
frame.Show(True)<br />
app.Ma<strong>in</strong>Loop()<br />
StatusBar<br />
PushStatusText()PopStatusText()<br />
<br />
<br />
6.3wx.StatusBar<br />
6.3 wx.StatusBar<br />
GetFieldsCount()<br />
SetFieldsCount(count)<br />
GetStatusText(field=0)<br />
151 / 565
SetStatusText(text, field=0)0<br />
<br />
PopStatusText(field=0)<br />
<br />
PushStatusText(text, field=0)<br />
<br />
SetStatusWidths(widths)widthsPython<br />
10<br />
6.2.2 <br />
<br />
<br />
6.3<br />
6.3<br />
<br />
wx.Menu.AppendMenu()<br />
wx.MenuAppendCheckItem()<br />
AppendRadioItem()wx.MenuItemk<strong>in</strong>d<br />
<br />
wx.ITEM_NORMAL, wx.ITEM_CHECKBOX, wx.ITEM_RADIO<br />
152 / 565
wx.MenuCheck(id,bool)id<br />
<strong>wxPython</strong> IDbool<br />
6.4<br />
5.5<br />
6.4<br />
ahW<strong>in</strong>dow<br />
class SketchFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self, parent):<br />
wx.Frame.__<strong>in</strong>it__(self, parent, -1, ”Sketch Frame”,<br />
size=(800,600))<br />
self.sketch = SketchW<strong>in</strong>dow(self, -1)<br />
self.sketch.B<strong>in</strong>d(wx.EVT_MOTION, self.OnSketchMotion)<br />
self.<strong>in</strong>itStatusBar() #1 <br />
self.createMenuBar()<br />
def <strong>in</strong>itStatusBar(self):<br />
self.statusbar = self.CreateStatusBar()<br />
self.statusbar.SetFieldsCount(3)<br />
self.statusbar.SetStatusWidths([-1, -2, -3])<br />
def OnSketchMotion(self, event):<br />
self.statusbar.SetStatusText(“Pos: %s” %<br />
str(event.GetPositionTuple()), 0)<br />
self.statusbar.SetStatusText(“Current Pts: %s” %<br />
len(self.sketch.curL<strong>in</strong>e), 1)<br />
self.statusbar.SetStatusText(“L<strong>in</strong>e Count: %s” %<br />
len(self.sketch.l<strong>in</strong>es), 2)<br />
event.Skip()<br />
def menuData(self): #2 <br />
return [(“&File”, (<br />
(“&New”, ”New Sketch file”, self.OnNew),<br />
(“&Open”, ”Open sketch file”, self.OnOpen),<br />
(“&Save”, ”Save sketch file”, self.OnSave),<br />
(“”, ””, ””),<br />
153 / 565
(“&Color”, (<br />
(“&Black”, ””, self.OnColor,<br />
wx.ITEM_RADIO),<br />
(“&Red”, ””, self.OnColor,<br />
wx.ITEM_RADIO),<br />
(“&Green”, ””, self.OnColor,<br />
wx.ITEM_RADIO),<br />
(“&Blue”, ””, self.OnColor,<br />
wx.ITEM_RADIO))),<br />
(“”, ””, ””),<br />
(“&Quit”, ”Quit”, self.OnCloseW<strong>in</strong>dow)))]<br />
def createMenuBar(self):<br />
menuBar = wx.MenuBar()<br />
for eachMenuData <strong>in</strong> self.menuData():<br />
menuLabel = eachMenuData[0]<br />
menuItems = eachMenuData[1]<br />
menuBar.Append(self.createMenu(menuItems), menuLabel)<br />
self.SetMenuBar(menuBar)<br />
def createMenu(self, menuData):<br />
menu = wx.Menu()<br />
#3 <br />
for eachItem <strong>in</strong> menuData:<br />
if len(eachItem) == 2:<br />
label = eachItem[0]<br />
subMenu = self.createMenu(eachItem[1])<br />
menu.AppendMenu(wx.NewId(), label, subMenu)<br />
else:<br />
self.createMenuItem(menu, *eachItem)<br />
return menu<br />
def createMenuItem(self, menu, label, status, handler,<br />
k<strong>in</strong>d=wx.ITEM_NORMAL):<br />
if not label:<br />
menu.AppendSeparator()<br />
return<br />
menuItem = menu.Append(-1, label, status, k<strong>in</strong>d)#4 k<strong>in</strong>d<br />
self.B<strong>in</strong>d(wx.EVT_MENU, handler, menuItem)<br />
154 / 565
def OnNew(self, event): pass<br />
def OnOpen(self, event): pass<br />
def OnSave(self, event): pass<br />
def OnColor(self, event):#5 <br />
menubar = self.GetMenuBar()<br />
itemId = event.GetId()<br />
item = menubar.F<strong>in</strong>dItemById(itemId)<br />
color = item.GetLabel()<br />
self.sketch.SetColor(color)<br />
def OnCloseW<strong>in</strong>dow(self, event):<br />
self.Destroy()<br />
if __name__ == ’__ma<strong>in</strong>__’:<br />
app = wx.PySimpleApp()<br />
frame = SketchFrame(None)<br />
frame.Show(True)<br />
app.Ma<strong>in</strong>Loop()<br />
<br />
#1__<strong>in</strong>it__<br />
<br />
#2(, ())<br />
(, , , k<strong>in</strong>d)<br />
2<br />
34XML<br />
#32<br />
createMenu<br />
#4wx.MenuItemk<strong>in</strong>d<br />
wx.Menu<br />
#5OnColor<br />
idF<strong>in</strong>dItemById()<br />
155 / 565
id<br />
<strong>wxPython</strong><br />
6.3 <br />
<br />
<br />
6.3.1 <br />
GUI<br />
<strong>wxPython</strong><br />
wx.FileDialog6.5sketch<br />
<br />
wx.FileDialog<br />
wx.FileDialog(parent, message=”Choose a file”, defaultDir=””,<br />
defaultFile=””, wildcard=”*.*”, style=0)<br />
6.6<br />
156 / 565
6.6 wx.FileDialog<br />
parentNone<br />
messagemessage<br />
defaultDir<br />
defaultFile<br />
wildcard|<br />
“Sketch files (*.sketch)|*.sketch|All files<br />
(*.*)|*.*”<br />
style6.7<br />
6.7 wx.FileDialog<br />
wx.CHANGE_DIR<br />
<br />
wx.MULTIPLE<br />
wx.OPEN<br />
wx.OVERWRITE_PROMPT<br />
<br />
wx.SAVE<br />
ShowModal()<br />
wx.ID_OKwx.ID_CANCEL<br />
GetFilename(), GetDirectory(), GetPath()<br />
Destroy()<br />
6.6SketchFrame<br />
““““cPickle<br />
oscPickle<br />
6.6 SketchFrame<br />
def __<strong>in</strong>it__(self, parent):<br />
self.title = ”Sketch Frame”<br />
157 / 565
wx.Frame.__<strong>in</strong>it__(self, parent, -1, self.title,<br />
size=(800,600))<br />
self.filename = ””<br />
self.sketch = SketchW<strong>in</strong>dow(self, -1)<br />
self.sketch.B<strong>in</strong>d(wx.EVT_MOTION, self.OnSketchMotion)<br />
self.<strong>in</strong>itStatusBar()<br />
self.createMenuBar()<br />
self.createToolBar()<br />
def SaveFile(self):#1 <br />
if self.filename:<br />
data = self.sketch.GetL<strong>in</strong>esData()<br />
f = open(self.filename, ’w’)<br />
cPickle.dump(data, f)<br />
f.close()<br />
def ReadFile(self):#2 <br />
if self.filename:<br />
try:<br />
f = open(self.filename, ’r’)<br />
data = cPickle.load(f)<br />
f.close()<br />
self.sketch.SetL<strong>in</strong>esData(data)<br />
except cPickle.Unpickl<strong>in</strong>gError:<br />
wx.MessageBox(“%s is not a sketch file.”<br />
% self.filename, ”oops!”,<br />
style=wx.OK|wx.ICON_EXCLAMATION)<br />
wildcard = ”Sketch files (*.sketch)|*.sketch|All files (*.*)|*.*”<br />
def OnOpen(self, event):#3 <br />
dlg = wx.FileDialog(self, ”Open sketch file...”,<br />
os.getcwd(), style=wx.OPEN,<br />
wildcard=self.wildcard)<br />
if dlg.ShowModal() == wx.ID_OK:<br />
self.filename = dlg.GetPath()<br />
self.ReadFile()<br />
self.SetTitle(self.title + ’ -- ’ + self.filename)<br />
dlg.Destroy()<br />
158 / 565
def OnSave(self, event):#4 <br />
if not self.filename:<br />
self.OnSaveAs(event)<br />
else:<br />
self.SaveFile()<br />
def OnSaveAs(self, event):#5 <br />
dlg = wx.FileDialog(self, ”Save sketch as...”,<br />
os.getcwd(),<br />
style=wx.SAVE | wx.OVERWRITE_PROMPT,<br />
wildcard=self.wildcard)<br />
if dlg.ShowModal() == wx.ID_OK:<br />
filename = dlg.GetPath()<br />
if not os.path.splitext(filename)[1]:#6 <br />
filename = filename + ’.sketch’<br />
self.filename = filename<br />
self.SaveFile()<br />
self.SetTitle(self.title + ’ -- ’ +<br />
self.filename)<br />
dlg.Destroy()<br />
#1cPickle<br />
#2cPickle<br />
<br />
#3OnOpen()wx.OPEN<br />
.sketchOK<br />
ReadFile()<br />
#4<br />
<br />
#5OnSave()wx.SAVE<br />
#6.sketch<br />
<br />
159 / 565
6.3.2 <br />
sketch<br />
<strong>wxPython</strong>wx.ColourDialog<br />
parent()<br />
wx.ColourData<br />
<br />
<br />
sketch<br />
6.7<br />
6.7 SketchFrame<br />
def menuData(self):<br />
return [(“&File”, (<br />
(“&New”, ”New Sketch file”, self.OnNew),<br />
(“&Open”, ”Open sketch file”, self.OnOpen),<br />
(“&Save”, ”Save sketch file”, self.OnSave),<br />
(“”, ””, ””),<br />
(“&Color”, (<br />
(“&Black”, ””, self.OnColor,<br />
wx.ITEM_RADIO),<br />
(“&Red”, ””, self.OnColor,<br />
wx.ITEM_RADIO),<br />
(“&Green”, ””, self.OnColor,<br />
wx.ITEM_RADIO),<br />
(“&Blue”, ””, self.OnColor,<br />
wx.ITEM_RADIO),<br />
(“&Other...”, ””, self.OnOtherColor,<br />
wx.ITEM_RADIO))),<br />
(“”, ””, ””),<br />
(“&Quit”, ”Quit”, self.OnCloseW<strong>in</strong>dow)))]<br />
def OnOtherColor(self, event):<br />
dlg = wx.ColourDialog(self)<br />
dlg.GetColourData().SetChooseFull(True)# <br />
if dlg.ShowModal() == wx.ID_OK:<br />
self.sketch.SetColor(dlg.GetColourData().GetColour())# <br />
<br />
160 / 565
dlg.Destroy()<br />
SetChooseFull()<br />
<br />
wx.Colorsketch<br />
6.4 <br />
<br />
<br />
about<br />
<br />
6.4.1 <br />
<strong>wxPython</strong><br />
<br />
<br />
<br />
<br />
<br />
<strong>wxPython</strong><br />
sizerJava AWT<br />
sizersizer<br />
wx.Panelsizersizer<br />
<br />
<br />
sizer<br />
1panelconta<strong>in</strong>er()<br />
2sizer<br />
3<br />
4sizerAdd()sizer<br />
sizersizer<br />
<br />
5sizersizersizer<br />
<br />
161 / 565
6SetSizer(sizer)<br />
6.8<strong>wxPython</strong>sizersizer<br />
11<br />
6.8 <strong>wxPython</strong>sizer<br />
wx.BoxSizerwx.BoxSizer<br />
sizer<br />
sizerbox<br />
<br />
wx.FlexGridSizerwx.GridSizer<br />
<br />
wx.GridSizer<br />
grid sizer<br />
<br />
wx.GridBagSizerwx.FlexGridSizer<br />
<br />
wx.StaticBoxSizerwx.BoxSizerbox<br />
<br />
<br />
sizersketch<br />
control panelcontrol panel<br />
wx.GridSizerwx.BoxSizer6.6<br />
panelsketchgridbox<br />
162 / 565
6.8control panelsketch<br />
sizer<br />
6.8<br />
def __<strong>in</strong>it__(self, parent):<br />
self.title = ”Sketch Frame”<br />
wx.Frame.__<strong>in</strong>it__(self, parent, -1, self.title,<br />
size=(800,600))<br />
self.filename = ””<br />
self.sketch = SketchW<strong>in</strong>dow(self, -1)<br />
self.sketch.B<strong>in</strong>d(wx.EVT_MOTION, self.OnSketchMotion)<br />
self.<strong>in</strong>itStatusBar()<br />
self.createMenuBar()<br />
self.createToolBar()<br />
self.createPanel()<br />
def createPanel(self):<br />
controlPanel = ControlPanel(self, -1, self.sketch)<br />
163 / 565
ox = wx.BoxSizer(wx.HORIZONTAL)<br />
box.Add(controlPanel, 0, wx.EXPAND)<br />
box.Add(self.sketch, 1, wx.EXPAND)<br />
self.SetSizer(box)<br />
6.8createPanel()ControlPanel<br />
box sizerwx.BoxSizer<br />
wx.HORIZONTALwx.VERTICALcontrolPanel<br />
SketchW<strong>in</strong>dowAdd()sizer<br />
sizerwx.BoxSizersizer<br />
sizer<br />
sizerstretch<br />
box sizer<br />
stretch0sizer<br />
0sizersizer<br />
wx.StatusBarsizer<br />
<br />
0controlPanel1<br />
sketch w<strong>in</strong>dow<br />
Add()<br />
wx.EXPANDsizer<br />
sizer6.7<br />
<br />
box sizer<br />
sketch w<strong>in</strong>dowcontrol panel<br />
<br />
<br />
6.8ControlPanelgridbox sizer6.9<br />
<br />
164 / 565
6.9 ControlPanel<br />
class ControlPanel(wx.Panel):<br />
BMP_SIZE = 16<br />
BMP_BORDER = 3<br />
NUM_COLS = 4<br />
SPACING = 4<br />
colorList = (‘Black’, ’Yellow’, ’Red’, ’Green’, ’Blue’, ’Purple’,<br />
’Brown’, ’Aquamar<strong>in</strong>e’, ’Forest Green’, ’Light Blue’,<br />
’Goldenrod’, ’Cyan’, ’Orange’, ’Navy’, ’Dark Grey’,<br />
’Light Grey’)<br />
maxThickness = 16<br />
def __<strong>in</strong>it__(self, parent, ID, sketch):<br />
wx.Panel.__<strong>in</strong>it__(self, parent, ID, style=wx.RAISED_BORDER)<br />
self.sketch = sketch<br />
buttonSize = (self.BMP_SIZE + 2 * self.BMP_BORDER,<br />
self.BMP_SIZE + 2 * self.BMP_BORDER)<br />
colorGrid = self.createColorGrid(parent, buttonSize)<br />
thicknessGrid = self.createThicknessGrid(buttonSize)<br />
self.layout(colorGrid, thicknessGrid)<br />
165 / 565
def createColorGrid(self, parent, buttonSize):#1 <br />
self.colorMap = {}<br />
self.colorButtons = {}<br />
colorGrid = wx.GridSizer(cols=self.NUM_COLS, hgap=2, vgap=2)<br />
for eachColor <strong>in</strong> self.colorList:<br />
bmp = parent.MakeBitmap(eachColor)<br />
b = buttons.GenBitmapToggleButton(self, -1, bmp, size=buttonSize)<br />
b.SetBezelWidth(1)<br />
b.SetUseFocusIndicator(False)<br />
self.B<strong>in</strong>d(wx.EVT_BUTTON, self.OnSetColour, b)<br />
colorGrid.Add(b, 0)<br />
self.colorMap[b.GetId()] = eachColor<br />
self.colorButtons[eachColor] = b<br />
self.colorButtons[self.colorList[0]].SetToggle(True)<br />
return colorGrid<br />
def createThicknessGrid(self, buttonSize):#2 <br />
self.thicknessIdMap = {}<br />
self.thicknessButtons = {}<br />
thicknessGrid = wx.GridSizer(cols=self.NUM_COLS, hgap=2, vgap=2)<br />
for x <strong>in</strong> range(1, self.maxThickness + 1):<br />
b = buttons.GenToggleButton(self, -1, str(x), size=buttonSize)<br />
b.SetBezelWidth(1)<br />
b.SetUseFocusIndicator(False)<br />
self.B<strong>in</strong>d(wx.EVT_BUTTON, self.OnSetThickness, b)<br />
thicknessGrid.Add(b, 0)<br />
self.thicknessIdMap[b.GetId()] = x<br />
self.thicknessButtons[x] = b<br />
self.thicknessButtons[1].SetToggle(True)<br />
return thicknessGrid<br />
def layout(self, colorGrid, thicknessGrid):#3 <br />
box = wx.BoxSizer(wx.VERTICAL)<br />
box.Add(colorGrid, 0, wx.ALL, self.SPACING)<br />
box.Add(thicknessGrid, 0, wx.ALL, self.SPACING)<br />
self.SetSizer(box)<br />
box.Fit(self)<br />
def OnSetColour(self, event):<br />
color = self.colorMap[event.GetId()]<br />
166 / 565
if color != self.sketch.color:<br />
self.colorButtons[self.sketch.color].SetToggle(False)<br />
self.sketch.SetColor(color)<br />
def OnSetThickness(self, event):<br />
thickness = self.thicknessIdMap[event.GetId()]<br />
if thickness != self.sketch.thickness:<br />
self.thicknessButtons[self.sketch.thickness].SetToggle(False)<br />
self.sketch.SetThickness(thickness)<br />
#1createColorGrid()grid sizer<br />
sizer4<br />
for<br />
<strong>wxPython</strong><br />
<br />
grid<br />
IDsizer<br />
<br />
#2createThicknessGrid()createColorGrid()<br />
grid sizer<br />
sizer<br />
#3box sizer(grid)grid<br />
0grid sizercontrol panel<br />
control panel<br />
Add()self.SPACING<br />
wx.ALL<br />
wx.ALL<br />
box sizerFit()control panelcontrol panel<br />
sizersizer<br />
sizer<br />
wx.Sizersizer6.9<br />
<br />
6.9 wx.Sizer<br />
Add(w<strong>in</strong>dow, proportion=0,flag=0, border=0,userData=None)<br />
167 / 565
Add(sizer, proportion=0,flag=0, border=0,userData=None)<br />
Add(size, proportion=0,flag=0, border=0,userData=None)<br />
wxW<strong>in</strong>dowsizer<br />
proportionwx.BoxSizer<br />
flag<br />
bordersizer<br />
userData<br />
<br />
Fit(w<strong>in</strong>dow)<br />
FitInside(w<strong>in</strong>dow )w<strong>in</strong>dowsizer<br />
sizerFitInside()<br />
scroll panel<br />
<br />
GetSize()wx.Sizesizer<br />
GetPosition()wx.Po<strong>in</strong>tsizer<br />
GetM<strong>in</strong>Size()wx.Sizesizer<br />
Layout()sizer<br />
<br />
Prepend(...)Add()sizer<br />
<br />
Remove(w<strong>in</strong>dow)<br />
Remove(sizer)<br />
Remove(nth)sizer<br />
SetDimension(x, y, width,height)sizer<br />
<br />
sizersizer11<br />
6.4.2 (about)<br />
about<br />
wx.html.HtmlW<strong>in</strong>dow<br />
wx.html.HtmlW<strong>in</strong>dow<br />
16wx.html.HtmlW<strong>in</strong>dow6.10<br />
HTML rendererabout<br />
168 / 565
6.10 wx.html.HtmlW<strong>in</strong>dowabout<br />
class SketchAbout(wx.Dialog):<br />
text = ’’’<br />
<br />
<br />
<br />
<br />
Sketch!<br />
<br />
<br />
<br />
Sketch is a demonstration program for <strong>wxPython</strong> In <strong>Action</strong><br />
Chapter 7. It is based on the SuperDoodle demo <strong>in</strong>cluded with <strong>wxPython</strong>,<br />
available at http://www.wxpython.org/<br />
<br />
SuperDoodle and <strong>wxPython</strong> are brought to you by<br />
Rob<strong>in</strong> Dunn and Total Control Software, Copyright<br />
1997-2006.<br />
<br />
<br />
‘’’<br />
def __<strong>in</strong>it__(self, parent):<br />
wx.Dialog.__<strong>in</strong>it__(self, parent, -1, ’About Sketch’,<br />
size=(440, 400) )<br />
html = wx.html.HtmlW<strong>in</strong>dow(self)<br />
html.SetPage(self.text)<br />
button = wx.Button(self, wx.ID_OK, ”Okay”)<br />
sizer = wx.BoxSizer(wx.VERTICAL)<br />
sizer.Add(html, 1, wx.EXPAND|wx.ALL, 5)<br />
sizer.Add(button, 0, wx.ALIGN_CENTER|wx.ALL, 5)<br />
self.SetSizer(sizer)<br />
self.Layout()<br />
169 / 565
HTML<br />
wx.html.HtmlW<strong>in</strong>dowwx.ID_OK ID<br />
box sizer<br />
6.8<br />
6.8<br />
(About)<br />
def OnAbout(self, event):<br />
dlg = SketchAbout(self)<br />
dlg.ShowModal()<br />
dlg.Destroy()<br />
6.4.3 <br />
<br />
<strong>wxPython</strong><br />
170 / 565
wx.SplashScreen<br />
<br />
<br />
wx.SplashScreen<br />
wx.SplashScreen(bitmap, splashStyle, milliseconds, parent, id,<br />
pos=wx.DefaultPosition, size=wx.DefaultSize,<br />
style=wx.SIMPLE_BORDER|wx.FRAME_NO_TASKBAR|wx.STAY_ON_TOP)<br />
6.10wx.SplashScreen<br />
6.10 wx.SplashScreen<br />
bitmapwx.Bitmap<br />
splashStyle<br />
wx.SPLASH_CENTRE_ON_PARENT,wx.SPLASH_CENTRE_ON_SCREEN,<br />
wx.SPLASH_NO_CENTRE, wx.SPLASH_TIMEOUT, wx.SPLASH_NO_TIMEOUT<br />
millisecondssplashStylewx.SPLASH_TIMEOUTmilliseconds<br />
<br />
parentNone<br />
idID-1<br />
possplashStylewx.SPLASH_NO_CENTERpos<br />
<br />
size<br />
style<strong>wxPython</strong><br />
6.11wx.App<br />
wx.PySimpleApp<br />
6.11 <br />
class SketchApp(wx.App):<br />
def OnInit(self):<br />
171 / 565
mp = wx.Image(“splash.png”).ConvertToBitmap()<br />
wx.SplashScreen(bmp, wx.SPLASH_CENTRE_ON_SCREEN | wx.SPLASH_<br />
TIMEOUT,<br />
1000, None, -1)<br />
wx.Yield()<br />
frame = SketchFrame(None)<br />
frame.Show(True)<br />
self.SetTopW<strong>in</strong>dow(frame)<br />
return True<br />
OnInit<br />
<br />
Yield()<br />
Yield()<br />
<br />
6.5 <br />
1<br />
<br />
sketch<br />
about<br />
<br />
2<strong>wxPython</strong><br />
API<br />
<br />
3<br />
<br />
4<br />
<br />
5wx.FileDialog<br />
wx.ColourDialog<br />
6sizer<br />
sizersizerwx.GridSizer<br />
172 / 565
wx.BoxSizersizersizer<br />
<br />
7aboutwx.html.HtmlW<strong>in</strong>dow<br />
wx.SplashScreen<br />
part 1<strong>wxPython</strong><br />
part 2<br />
<strong>wxPython</strong><br />
<br />
173 / 565
Part 2 <strong>wxPython</strong><br />
<strong>wxPython</strong><br />
<strong>wxPython</strong><br />
API<br />
<br />
7“”<br />
<br />
<br />
8“”<br />
<br />
9“<br />
”<br />
<strong>wxPython</strong><br />
<br />
“<strong>wxPython</strong>”<br />
<br />
toggle menus<br />
11“sizer”sizersizer<br />
<strong>wxPython</strong>6<br />
sizer<br />
12“”<br />
<br />
<br />
174 / 565
7<br />
<strong>wxPython</strong><br />
<br />
<br />
<strong>wxPython</strong> API<br />
7.1 <br />
<br />
<br />
<br />
7.1.1 <br />
UI<br />
<strong>wxPython</strong>wx.StaticText7.1<br />
wx.StaticText<br />
<br />
wx.html.HTMLW<strong>in</strong>dow<br />
<br />
7.1<br />
wx.StaticText<br />
175 / 565
7.17.1<br />
7.1 <br />
import wx<br />
class StaticTextFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, -1, ’Static Text Example’,<br />
size=(400, 300))<br />
panel = wx.Panel(self, -1)<br />
# <br />
wx.StaticText(panel, -1, ”This is an example of static text”,<br />
(100, 10))<br />
# <br />
rev = wx.StaticText(panel, -1, ”Static Text With Reversed Colors”,<br />
(100, 30))<br />
rev.SetForegroundColour(‘white’)<br />
rev.SetBackgroundColour(‘black’)<br />
# <br />
center = wx.StaticText(panel, -1, ”align center”, (100, 50),<br />
(160, -1), wx.ALIGN_CENTER)<br />
center.SetForegroundColour(‘white’)<br />
center.SetBackgroundColour(‘black’)<br />
# <br />
right = wx.StaticText(panel, -1, ”align right”, (100, 70),<br />
(160, -1), wx.ALIGN_RIGHT)<br />
right.SetForegroundColour(‘white’)<br />
right.SetBackgroundColour(‘black’)<br />
# <br />
str = ”You can also change the font.”<br />
text = wx.StaticText(panel, -1, str, (20, 100))<br />
font = wx.Font(18, wx.DECORATIVE, wx.ITALIC, wx.NORMAL)<br />
176 / 565
text.SetFont(font)<br />
# <br />
wx.StaticText(panel, -1, ”Your text\ncan be split\n”<br />
”over multiple l<strong>in</strong>es\n\neven blank ones”, (20,150))<br />
#<br />
wx.StaticText(panel, -1, ”Multi-l<strong>in</strong>e text\ncan also\n”<br />
”be right aligned\n\neven with a blank”, (220,150),<br />
style=wx.ALIGN_RIGHT)<br />
if __name__ == ’__ma<strong>in</strong>__’:<br />
app = wx.PySimpleApp()<br />
frame = StaticTextFrame()<br />
frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
wx.StaticTextwxWidget<br />
wx.StaticText(parent, id, label, pos=wx.DefaultPosition,<br />
size=wx.DefaultSize, style=0, name=”staticText”)<br />
7.1——<strong>wxPython</strong><br />
2<br />
7.1 wx.StaticText<br />
parent<br />
id-1<br />
label<br />
poswx.Po<strong>in</strong>tPython<br />
sizewx.SizePython<br />
style<br />
name<br />
177 / 565
7.1wx.W<strong>in</strong>dow<br />
wx.StaticText7.2<br />
wx.StaticText<br />
7.2<br />
wx.ALIGN_CENTER<br />
wx.ALIGN_LEFT<br />
wx.ALIGN_RIGHT<br />
wx.ST_NO_AUTORESIZESetLabel()<br />
<br />
<br />
wx.StaticTextSetLabel()<br />
wx.ST_NO_AUTORESIZE<br />
<br />
<strong>wxPython</strong><strong>wxPython</strong><br />
<br />
<br />
wx.ST_NO_AUTORESIZE<br />
<br />
<br />
<br />
wx.lib.stattext.GenStaticText<br />
wx.StaticTextPythonC++<br />
<br />
<br />
DrawText(text, x,y)DrawRotatedText(text, x, y, angle)<br />
<br />
178 / 565
GenStaticText6<br />
12<br />
7.1.2 <br />
<br />
<strong>wxPython</strong>wx.TextCtrl<br />
<br />
wx.TextCtrl<br />
7.2wx.TextCtrl<br />
<br />
<br />
<br />
7.27.2<br />
7.2 wx.TextCtrl<br />
import wx<br />
class TextFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, -1, ’Text Entry Example’,<br />
size=(300, 100))<br />
panel = wx.Panel(self, -1)<br />
basicLabel = wx.StaticText(panel, -1, ”Basic Control:”)<br />
basicText = wx.TextCtrl(panel, -1, ”I’ve entered some text!”,<br />
size=(175, -1))<br />
basicText.SetInsertionPo<strong>in</strong>t(0)<br />
179 / 565
pwdLabel = wx.StaticText(panel, -1, ”Password:”)<br />
pwdText = wx.TextCtrl(panel, -1, ”password”, size=(175, -1),<br />
style=wx.TE_PASSWORD)<br />
sizer = wx.FlexGridSizer(cols=2, hgap=6, vgap=6)<br />
sizer.AddMany([basicLabel, basicText, pwdLabel, pwdText])<br />
panel.SetSizer(sizer)<br />
if __name__ == ’__ma<strong>in</strong>__’:<br />
app = wx.PySimpleApp()<br />
frame = TextFrame()<br />
frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
wx.TextCtrlwx.W<strong>in</strong>dow<br />
<br />
wx.TextCtrl(parent, id, value = ””, pos=wx.DefaultPosition,<br />
size=wx.DefaultSize, style=0, validator=wx.DefaultValidator<br />
name=wx.TextCtrlNameStr)<br />
parent, id, pos, size, style, namewx.W<strong>in</strong>dowvalue<br />
<br />
validatorwx.Validatorvalidator<br />
9validator<br />
<br />
<br />
7.3<br />
7.3 wx.TextCtrl<br />
wx.TE_CENTER<br />
wx.TE_LEFT<br />
wx.TE_NOHIDESELW<strong>in</strong>dows<br />
wx.TE_PASSWORD<br />
180 / 565
wx.TE_PROCESS_ENTER<br />
<br />
<br />
wx.TE_PROCESS_TABTab<br />
tab<br />
<br />
wx.TE_READONLY<br />
wx.TE_RIGHT<br />
|<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
7.1.3 <br />
wx.TextCtrl<br />
<br />
7.4wx.TextCtrl<br />
7.4<br />
AppendText(text)<br />
Clear()“”<br />
EmulateKeyPress(event)<br />
<br />
GetInsertionPo<strong>in</strong>t()<br />
SetInsertionPo<strong>in</strong>t(pos)<br />
SetInsertionPo<strong>in</strong>tEnd()<br />
0<br />
181 / 565
GetRange(from, to)<br />
GetSelection()<br />
GetStr<strong>in</strong>gSelection()<br />
SetSelection(from, to)GetSelection()<br />
GetStr<strong>in</strong>gSelection()<br />
SetSelection(from, to)<br />
GetValue()<br />
SetValue(value)SetValue()GetValue()<br />
<br />
Remove(from, to)<br />
Replace(from, to, value)<br />
<br />
WriteText(text)AppendText()<br />
<br />
<br />
7.1.4 <br />
wx.TE_MULTILINE<br />
<br />
<br />
7.3<br />
182 / 565
7.37.3<br />
wx.TE_MULTILINE<br />
<br />
7.3 <br />
import wx<br />
class TextFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, -1, ’Text Entry Example’,<br />
size=(300, 250))<br />
panel = wx.Panel(self, -1)<br />
multiLabel = wx.StaticText(panel, -1, ”Multi-l<strong>in</strong>e”)<br />
multiText = wx.TextCtrl(panel, -1,<br />
”Here is a looooooooooooooong l<strong>in</strong>e of text set <strong>in</strong> the control.\n\n”<br />
”See that it wrapped, and that this l<strong>in</strong>e is after a blank”,<br />
size=(200, 100), style=wx.TE_MULTILINE) #<br />
multiText.SetInsertionPo<strong>in</strong>t(0) #<br />
richLabel = wx.StaticText(panel, -1, ”Rich Text”)<br />
richText = wx.TextCtrl(panel, -1,<br />
”If supported by the native control, this is reversed, and this is a different<br />
font.”,<br />
size=(200, 100), style=wx.TE_MULTILINE|wx.TE_RICH2) #<br />
<br />
richText.SetInsertionPo<strong>in</strong>t(0)<br />
richText.SetStyle(44, 52, wx.TextAttr(“white”, ”black”)) #<br />
po<strong>in</strong>ts = richText.GetFont().GetPo<strong>in</strong>tSize()<br />
f = wx.Font(po<strong>in</strong>ts + 3, wx.ROMAN, wx.ITALIC, wx.BOLD, True) #<br />
<br />
richText.SetStyle(68, 82, wx.TextAttr(“blue”, wx.NullColour, f)) #<br />
<br />
sizer = wx.FlexGridSizer(cols=2, hgap=6, vgap=6)<br />
sizer.AddMany([multiLabel, multiText, richLabel, richText])<br />
panel.SetSizer(sizer)<br />
183 / 565
if __name__ == ’__ma<strong>in</strong>__’:<br />
app = wx.PySimpleApp()<br />
frame = TextFrame()<br />
frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
<br />
wx.TE_MULTILINE<br />
7.5<br />
7.5<br />
wx.HSCROLL<br />
GTK+<br />
wx.TE_AUTO_URL<br />
URLURL<br />
wx.TE_DONTWRAPwx.HSCROLL<br />
wx.TE_LINEWRAP<br />
<br />
wx.TE_MULTILINE<br />
wx.TE_RICHW<strong>in</strong>dows<br />
<br />
wx.TE_RICH2W<strong>in</strong>dows<br />
<br />
wx.TE_WORDWRAP<br />
<br />
<br />
wx.TE_MULTILINE | wx.TE_RICH2<br />
wx.TextCtrlwx.TextAttrwx.TextAttr<br />
<br />
<br />
wx.TextAttr(colText, colBack=wx.NullColor, font=wx.NullFont)<br />
184 / 565
<strong>wxPython</strong>RGB<br />
(, , )wx.NullColorfont<br />
wx.Fontwx.NullFont<br />
<br />
wx.TextAttrget*()<br />
GetBackgroundColour(), GetFont(), GetTextColour()<br />
HasBackgroundColour(), HasFont(), HasTextColour()<br />
Has*()False<br />
IsDefault()trueset*()wx.TextAttr<br />
<br />
SetDefaultStyle(style)SetStyle(start, end,style)<br />
<br />
AppendText() WriteText()<br />
<br />
SetStyle()SetDefaultStyle(style)<br />
start end<br />
7.3<br />
<br />
richText.SetStyle(44, 52, wx.TextAttr(“white”, ”black”))<br />
<br />
7.6wx.TextCtrl<br />
<br />
7.6<br />
GetDefaultStyle()<br />
SetDefaultStyle(style)<br />
GetL<strong>in</strong>eLength(l<strong>in</strong>eNo)<br />
GetL<strong>in</strong>eText(l<strong>in</strong>eNo)<br />
GetNumberOfL<strong>in</strong>es()1<br />
IsMultiL<strong>in</strong>e()<br />
185 / 565
IsS<strong>in</strong>gleL<strong>in</strong>e()<br />
PositionToXY(pos)()<br />
0<br />
SetStyle(start, end,style)<br />
ShowPosition(pos)<br />
XYToPosition(x, y)PositionToXY(pos)——<br />
<br />
<br />
7.1.5 <br />
wx.Font<br />
<br />
wx.Font(po<strong>in</strong>tSize, family, style, weight, underl<strong>in</strong>e=False,<br />
faceName=””, encod<strong>in</strong>g=wx.FONTENCODING_DEFAULT)<br />
po<strong>in</strong>tSizefamily<br />
<br />
7.7<br />
<br />
7.7<br />
wx.DECORATIVE<br />
wx.DEFAULT<br />
wx.MODERN<br />
wx.ROMANserifTimes New Roman<br />
wx.SCRIPT<br />
wx.SWISSsans-serifHelveticaArial<br />
style<br />
wx.NORMAL, wx.SLANT, wx.ITALICweight<br />
186 / 565
wx.NORMAL, wx.LIGHT,wx.BOLD<br />
underl<strong>in</strong>eW<strong>in</strong>dows<br />
TrueFalse<br />
faceName<br />
encod<strong>in</strong>g<br />
Unicode<strong>wxPython</strong>8<br />
<br />
<br />
wx.FontEnumerator<br />
e = wx.FontEnumerator()<br />
e.EnumerateFacenames()<br />
fontList = e.GetFacenames()<br />
<br />
e = wx.FontEnumerator(fixedWidth=True)<br />
7.1.6 <br />
<strong>wxPython</strong><br />
wx.stc.StyledTextCtrlPythonSc<strong>in</strong>tillaSc<strong>in</strong>tilla<br />
wxWidgets<strong>wxPython</strong><br />
APIwx.stc.StyledCtrl<br />
http://wiki.wxpython.org/<strong>in</strong>dex.cgi/<br />
wxStyledTextCtrl<br />
7.1.7 <br />
wx.TextCtrl<br />
wx.TextCtrl\n<br />
<br />
GetValue()<br />
<br />
<br />
<br />
W<strong>in</strong>dows\r\n<br />
187 / 565
GetValue()GetLastPosition()<br />
7.3<br />
pr<strong>in</strong>t ”getValue”, len(multiText.GetValue())<br />
pr<strong>in</strong>t ”lastPos”, multiText.GetLastPosition()<br />
Unix<br />
getValue 119<br />
lastPos 119<br />
W<strong>in</strong>dows<br />
getValue 121<br />
lastPos 119<br />
<br />
wx.TextCtrl<br />
GetRange()GetSelectedText()<br />
<br />
10<br />
aLongStr<strong>in</strong>g = ”””Any old<br />
multi l<strong>in</strong>e str<strong>in</strong>g<br />
will do here.<br />
Just as long as<br />
it is multil<strong>in</strong>e”””<br />
text = wx.TextCtrl(panel, -1, aLongStr<strong>in</strong>g, style=wx.TE_MULTILINE)<br />
x = text.GetInsertionPo<strong>in</strong>t()<br />
selection = aLongStr<strong>in</strong>g[x : x + 10] ### <br />
W<strong>in</strong>dowsMac<br />
selection = text.GetRange(x, x + 10)<br />
7.1.8 <br />
wx.TextCtrl<br />
B<strong>in</strong>d<br />
188 / 565
frame.B<strong>in</strong>d(wx.EVT_TEXT, frame.OnText, text)<br />
7.8<br />
7.8 wx.TextCtrl<br />
EVT_TEXT<br />
SetValue()<br />
EVT_TEXT_ENTERwx.TE_PROCESS_ENTER<br />
<br />
EVT_TEXT_URLW<strong>in</strong>dowswx.TE_RICHwx.TE_RICH2<br />
wx.TE_AUTO_URLURL<br />
<br />
EVT_TEXT_MAXLENSetMaxLength()<br />
<br />
<br />
<br />
<br />
7.2 <br />
<strong>wxPython</strong><br />
toggle buttonsgeneric<br />
7.2.1 <br />
part 1<br />
7.4<br />
7.4<br />
189 / 565
7.4<br />
7.4 <br />
import wx<br />
class ButtonFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, -1, ’Button Example’,<br />
size=(300, 100))<br />
panel = wx.Panel(self, -1)<br />
self.button = wx.Button(panel, -1, ”Hello”, pos=(50, 20))<br />
self.B<strong>in</strong>d(wx.EVT_BUTTON, self.OnClick, self.button)<br />
self.button.SetDefault()<br />
def OnClick(self, event):<br />
self.button.SetLabel(“Clicked”)<br />
if __name__ == ’__ma<strong>in</strong>__’:<br />
app = wx.PySimpleApp()<br />
frame = ButtonFrame()<br />
frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
wx.Button<br />
wx.Button(parent, id, label, pos, size=wxDefaultSize, style=0,<br />
validator, name=”button”)<br />
labelSetLabel()<br />
GetLabel()GetDefaultSize()<br />
SetDefault()GetDefaultSize()<br />
SetDefault()<br />
<br />
wx.Buttonwx.BU_EXACTFIT<br />
<br />
<br />
wx.BU_LEFT, wx.BU_RIGHT, wx.BU_TOP, wx.BU_BOTTOM<br />
190 / 565
wx.Button<br />
EVT_BUTTON<br />
7.2.2 <br />
<br />
7.5<br />
<strong>wxPython</strong>wx.BitmapButton<br />
wx.BitmapButton7.57.5<br />
<br />
7.5 <br />
import wx<br />
class BitmapButtonFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, -1, ’Bitmap Button Example’,<br />
size=(200, 150))<br />
panel = wx.Panel(self, -1)<br />
bmp = wx.Image(“bitmap.bmp”, wx.BITMAP_TYPE_BMP).ConvertToBitmap<br />
()<br />
self.button = wx.BitmapButton(panel, -1, bmp, pos=(10, 20))<br />
self.B<strong>in</strong>d(wx.EVT_BUTTON, self.OnClick, self.button)<br />
self.button.SetDefault()<br />
self.button2 = wx.BitmapButton(panel, -1, bmp, pos=(100, 20),<br />
style=0)<br />
self.B<strong>in</strong>d(wx.EVT_BUTTON, self.OnClick, self.button2)<br />
191 / 565
def OnClick(self, event):<br />
self.Destroy()<br />
if __name__ == ’__ma<strong>in</strong>__’:<br />
app = wx.PySimpleApp()<br />
frame = BitmapButtonFrame()<br />
frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
<br />
<br />
EVT_BUTTON<br />
<br />
wx.BU_AUTODRAW<br />
3D7.5<br />
<br />
style=07.53D<br />
<br />
<strong>wxPython</strong><br />
<strong>wxPython</strong><br />
<br />
<br />
SetBitmapDisabled(), SetBitmapFocus(),SetBitmapLabel(), SetBitmap-<br />
Selected()<strong>wxPython</strong><br />
wx.Bitmapget*()<br />
wxWidgets C++<br />
<br />
<strong>wxPython</strong><br />
7.2.3 toggle button<br />
wx.ToggleButtontoggle button<br />
toggle button<br />
toggle button<br />
<br />
192 / 565
wx.ToggleButtonwx.Button<br />
1wx.ToggleButtonEVT_TOGGLEBUTTON<br />
2wx.ToggleButtonGetValue()SetValue()<br />
<br />
toggle button<br />
wxWidgets<br />
toggle button<strong>wxPython</strong><br />
<br />
7.2.4 <br />
Python<br />
wx.lib.buttons. GenButton<br />
<br />
<br />
1<br />
<br />
2<br />
3D<br />
3wxWidget<br />
GenBitmapTextButtonGenBitmapToggleButton<br />
<br />
4<br />
Python<br />
<br />
7.6<br />
193 / 565
7.6<br />
7.67.6<br />
import wx.lib.buttons as buttons<br />
7.6 <strong>wxPython</strong><br />
import wx<br />
import wx.lib.buttons as buttons<br />
class GenericButtonFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, -1, ’Generic Button Example’,<br />
size=(500, 350))<br />
panel = wx.Panel(self, -1)<br />
sizer = wx.FlexGridSizer(1, 3, 20, 20)<br />
b = wx.Button(panel, -1, ”A wx.Button”)<br />
b.SetDefault()<br />
sizer.Add(b)<br />
b = wx.Button(panel, -1, ”non-default wx.Button”)<br />
sizer.Add(b)<br />
sizer.Add((10,10))<br />
b = buttons.GenButton(panel, -1, ’Genric Button’)#<br />
sizer.Add(b)<br />
194 / 565
= buttons.GenButton(panel, -1, ’disabled Generic’)#<br />
b.Enable(False)<br />
sizer.Add(b)<br />
b = buttons.GenButton(panel, -1, ’bigger’)#<br />
b.SetFont(wx.Font(20, wx.SWISS, wx.NORMAL, wx.BOLD, False))<br />
b.SetBezelWidth(5)<br />
b.SetBackgroundColour(“Navy”)<br />
b.SetForegroundColour(“white”)<br />
b.SetToolTipStr<strong>in</strong>g(“This is a BIG button...”)<br />
sizer.Add(b)<br />
()<br />
bmp = wx.Image(“bitmap.bmp”, wx.BITMAP_TYPE_BMP).ConvertToBitmap<br />
b = buttons.GenBitmapButton(panel, -1, bmp)#<br />
sizer.Add(b)<br />
b = buttons.GenBitmapToggleButton(panel, -1, bmp)#<br />
sizer.Add(b)<br />
b = buttons.GenBitmapTextButton(panel, -1, bmp, ”Bitmapped Text”,<br />
size=(175, 75))#<br />
b.SetUseFocusIndicator(False)<br />
sizer.Add(b)<br />
b = buttons.GenToggleButton(panel, -1, ”Toggle Button”)#<br />
sizer.Add(b)<br />
panel.SetSizer(sizer)<br />
if __name__ == ’__ma<strong>in</strong>__’:<br />
app = wx.PySimpleApp()<br />
frame = GenericButtonFrame()<br />
frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
7.6<br />
EVT_BUTTON EVT_TOGGLEBUTTON<br />
GetBevelWidth()SetBevelWidth()3D7.6<br />
<br />
195 / 565
GenBitmapButton<strong>wxPython</strong><br />
GenBitmapTextButton<br />
GenToggleButton,GenBitmapToggleButton,<br />
GenBitmapTextToggleButton<br />
GetToggle() SetToggle()<br />
<br />
<br />
7.3 <br />
<br />
<strong>wxPython</strong><br />
slider<br />
7.3.1 <br />
<br />
<strong>wxPython</strong>wx.Slider<br />
7.7<br />
7.7<br />
<br />
196 / 565
7.77.7<br />
7.7 <br />
import wx<br />
class SliderFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, -1, ’Slider Example’,<br />
size=(300, 350))<br />
panel = wx.Panel(self, -1)<br />
self.count = 0<br />
slider = wx.Slider(panel, 100, 25, 1, 100, pos=(10, 10),<br />
size=(250, -1),<br />
style=wx.SL_HORIZONTAL | wx.SL_AUTOTICKS | wx.SL_LABELS )<br />
slider.SetTickFreq(5, 1)<br />
slider = wx.Slider(panel, 100, 25, 1, 100, pos=(125, 70),<br />
size=(-1, 250),<br />
style=wx.SL_VERTICAL | wx.SL_AUTOTICKS | wx.SL_LABELS )<br />
slider.SetTickFreq(20, 1)<br />
if __name__ == ’__ma<strong>in</strong>__’:<br />
app = wx.PySimpleApp()<br />
frame = SliderFrame()<br />
frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
wx.Slider<br />
<br />
wx.Slider(parent, id, value, m<strong>in</strong>Value, maxValue,<br />
pos=wxDefaultPosition, size=wx.DefaultSize,<br />
style=wx.SL_HORIZONTAL, validator=wx.DefaultValidator,<br />
name=”slider”)<br />
valuem<strong>in</strong>ValuemaxValue<br />
197 / 565
7.9<br />
7.9 wx.Slider<br />
wx.SL_AUTOTICKS<br />
SetTickFreq<br />
wx.SL_HORIZONTAL<br />
wx.SL_LABELS<br />
<br />
wx.SL_LEFT<br />
wx.SL_RIGHT<br />
wx.SL_TOP<br />
wx.SL_VERTICAL<br />
<br />
<br />
8<br />
7.10Set*()Set*()<br />
Get——GetSet*()<br />
7.10<br />
GetRange()<br />
SetRange(m<strong>in</strong>Value, maxValue)<br />
GetTickFreq()<br />
SetTickFreq(n, pos)npos<br />
1<br />
GetL<strong>in</strong>eSize()<br />
SetL<strong>in</strong>eSize(l<strong>in</strong>eSize)<br />
GetPageSize()<br />
SetPageSize(pageSize)PgUpPgDn<br />
<br />
198 / 565
GetValue()<br />
SetValue(value)<br />
<br />
<br />
<br />
7.3.2 <br />
<br />
7.8<br />
<strong>wxPython</strong><br />
7.8<br />
<strong>wxPython</strong>wx.Sp<strong>in</strong>Ctrl<br />
<br />
<br />
wx.Sp<strong>in</strong>Ctrl<br />
<br />
<br />
7.8wx.Sp<strong>in</strong>Ctrl<br />
7.8 wx.Sp<strong>in</strong>Ctrl<br />
import wx<br />
class Sp<strong>in</strong>nerFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, -1, ’Sp<strong>in</strong>ner Example’,<br />
199 / 565
size=(100, 100))<br />
panel = wx.Panel(self, -1)<br />
sc = wx.Sp<strong>in</strong>Ctrl(panel, -1, ””, (30, 20), (80, -1))<br />
sc.SetRange(1,100)<br />
sc.SetValue(5)<br />
if __name__ == ’__ma<strong>in</strong>__’:<br />
app = wx.PySimpleApp()<br />
Sp<strong>in</strong>nerFrame().Show()<br />
app.Ma<strong>in</strong>Loop()<br />
<br />
wx.Sp<strong>in</strong>Ctrl(parent, id=-1, value=wx.EmptyStr<strong>in</strong>g,<br />
pos=wx.DefaultPosition, size=wx.DefaultSize,<br />
style=wx.SP_ARROW_KEYS, m<strong>in</strong>=0, max=100, <strong>in</strong>itial=0,<br />
name=”wxSp<strong>in</strong>Ctrl”)<br />
value<strong>in</strong>itialm<strong>in</strong>max<br />
<br />
wx.Sp<strong>in</strong>Ctrlwx.SP_ARROW_KEYS<br />
wx.SP_WRAP<br />
<br />
<br />
EVT_SPINCTRL<br />
EVT_TEXT<br />
<br />
7.8SetRange(m<strong>in</strong>Val, maxVal) SetValue(value)<br />
SetValue()<br />
GetValue(), GetM<strong>in</strong>(), GetMax()<br />
<br />
wx.Sp<strong>in</strong>Buttonwx.TextCtrl<br />
wx.Sp<strong>in</strong>Buttonwx.TextCtrl<br />
<br />
200 / 565
7.3.3 <br />
<br />
<strong>wxPython</strong>wx.Gauge<br />
7.9<br />
7.9<br />
7.97.9<br />
<br />
<br />
7.9 wx.Gauge<br />
import wx<br />
class GaugeFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, -1, ’Gauge Example’,<br />
size=(350, 150))<br />
panel = wx.Panel(self, -1)<br />
self.count = 0<br />
self.gauge = wx.Gauge(panel, -1, 50, (20, 50), (250, 25))<br />
self.gauge.SetBezelFace(3)<br />
self.gauge.SetShadowWidth(3)<br />
self.B<strong>in</strong>d(wx.EVT_IDLE, self.OnIdle)<br />
def OnIdle(self, event):<br />
self.count = self.count + 1<br />
if self.count >= 50:<br />
self.count = 0<br />
201 / 565
self.gauge.SetValue(self.count)<br />
if __name__ == ’__ma<strong>in</strong>__’:<br />
app = wx.PySimpleApp()<br />
GaugeFrame().Show()<br />
app.Ma<strong>in</strong>Loop()<br />
wx.Gauge<br />
wx.Gauge(parent, id, range, pos=wx.DefaultPosition,<br />
size=wx.DefaultSize, style=wx.GA_HORIZONTAL,<br />
validator=wx.DefaultValidator, name=”gauge”)<br />
range<br />
0wx.GA_HORIZONTAL90<br />
wx.GA_VERTICALW<strong>in</strong>dows<br />
wx.GA_PROGRESSBARW<strong>in</strong>dows<br />
wx.Gauge<br />
GetValue(), Set-Value(pos), GetRange(), SetRange(range)<br />
W<strong>in</strong>dows<br />
SetBezelFace(width) and SetShadowWidth()3D<br />
7.4 <br />
<br />
<strong>wxPython</strong><br />
<br />
7.4.1 <br />
<br />
<br />
7.10<br />
202 / 565
7.10<br />
<strong>wxPython</strong>wx.CheckBox<br />
7.10<br />
7.10<br />
7.10 <br />
import wx<br />
class CheckBoxFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, -1, ’Checkbox Example’,<br />
size=(150, 200))<br />
panel = wx.Panel(self, -1)<br />
wx.CheckBox(panel, -1, ”Alpha”, (35, 40), (150, 20))<br />
wx.CheckBox(panel, -1, ”Beta”, (35, 60), (150, 20))<br />
wx.CheckBox(panel, -1, ”Gamma”, (35, 80), (150, 20))<br />
if __name__ == ’__ma<strong>in</strong>__’:<br />
app = wx.PySimpleApp()<br />
CheckBoxFrame().Show()<br />
app.Ma<strong>in</strong>Loop()<br />
wx.CheckBox<strong>wxPython</strong><br />
wx.CheckBox(parent, id, label, pos=wx.DefaultPosition,<br />
size=wx.DefaultSize, style=0, name=”checkBox”)<br />
203 / 565
label<br />
EVT_CHECKBOXwx.CheckBox<br />
GetValue()SetValue(state),<br />
IsChecked()GetValue()<br />
7.4.2 radio button<br />
<br />
<br />
<br />
radio button<br />
<br />
<strong>wxPython</strong><br />
wx.RadioButtonwx.RadioBox<br />
<br />
wx.RadioButton<br />
7.11<br />
wx.RadioButton<br />
7.11<br />
wx.RadioButton<br />
<br />
<br />
204 / 565
7.117.11<br />
7.11 wx.RadioButton<br />
import wx<br />
class RadioButtonFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, -1, ’Radio Example’,<br />
size=(200, 200))<br />
panel = wx.Panel(self, -1)<br />
#<br />
radio1 = wx.RadioButton(panel, -1, ”Elmo”, pos=(20, 50), style=wx.RB_GRO<br />
UP)<br />
radio2 = wx.RadioButton(panel, -1, ”Ernie”, pos=(20, 80))<br />
radio3 = wx.RadioButton(panel, -1, ”Bert”, pos=(20, 110))<br />
#<br />
text1 = wx.TextCtrl(panel, -1, ””, pos=(80, 50))<br />
text2 = wx.TextCtrl(panel, -1, ””, pos=(80, 80))<br />
text3 = wx.TextCtrl(panel, -1, ””, pos=(80, 110))<br />
self.texts = {“Elmo”: text1, ”Ernie”: text2, ”Bert”: text3}#<br />
for eachText <strong>in</strong> [text2, text3]:<br />
eachText.Enable(False)<br />
for eachRadio <strong>in</strong> [radio1, radio2, radio3]:#<br />
self.B<strong>in</strong>d(wx.EVT_RADIOBUTTON, self.OnRadio, eachRadio)<br />
self.selectedText = text1<br />
def OnRadio(self, event):#<br />
if self.selectedText:<br />
self.selectedText.Enable(False)<br />
radioSelected = event.GetEventObject()<br />
text = self.texts[radioSelected.GetLabel()]<br />
text.Enable(True)<br />
self.selectedText = text<br />
if __name__ == ’__ma<strong>in</strong>__’:<br />
205 / 565
app = wx.PySimpleApp()<br />
RadioButtonFrame().Show()<br />
app.Ma<strong>in</strong>Loop()<br />
<br />
forfor<br />
<br />
<br />
wx.RadioButtonwx.CheckBox<br />
<br />
wx.RadioButton(parent, id, label, pos=wx.DefaultPosition,<br />
size=wx.DefaultSize, style=0,<br />
validator=wx.DefaultValidator, name=”radioButton”)<br />
label<br />
wx.RB_GROUP<br />
<br />
wx.RB_GROUP<br />
<br />
wx.RB_GROUP7.11<br />
wx.RB_GROUP<br />
<br />
<br />
<br />
<br />
<strong>wxPython</strong>wx.RadioBox<br />
7.12<br />
206 / 565
7.12<br />
wx.RadioBox7.12<br />
7.12<br />
7.12 <br />
import wx<br />
class RadioBoxFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, -1, ’Radio Box Example’,<br />
size=(350, 200))<br />
panel = wx.Panel(self, -1)<br />
sampleList = [‘zero’, ’one’, ’two’, ’three’, ’four’, ’five’,<br />
’six’, ’seven’, ’eight’]<br />
wx.RadioBox(panel, -1, ”A Radio Box”, (10, 10), wx.DefaultSize,<br />
sampleList, 2, wx.RA_SPECIFY_COLS)<br />
wx.RadioBox(panel, -1, ””, (150, 10), wx.DefaultSize,<br />
sampleList, 3, wx.RA_SPECIFY_COLS | wx.NO_BORDER)<br />
if __name__ == ’__ma<strong>in</strong>__’:<br />
app = wx.PySimpleApp()<br />
RadioBoxFrame().Show()<br />
app.Ma<strong>in</strong>Loop()<br />
207 / 565
wx.RadioBox<br />
<br />
wx.RadioBox(parent, id, label, pos=wx.DefaultPosition,<br />
size=wxDefaultSize, choices=None, majorDimension=0,<br />
style=wx.RA_SPECIFY_COLS, validator=wx.DefaultValidator,<br />
name=”radioBox”)<br />
labelchoices<br />
Python<br />
sizer<br />
wx.RadioBox<strong>wxPython</strong><br />
majorDimension<br />
wx.RA_SPECIFY_COLS2<br />
3choices<br />
wx.RA_SPECIFY_ROWS<br />
EVT_RADIOBOX<br />
wx.RadioBox<br />
0<br />
7.11<br />
<br />
7.11 wx.RadioBox<br />
EnableItem(n, flag)flagn<br />
Enable()<br />
F<strong>in</strong>dStr<strong>in</strong>g(str<strong>in</strong>g)<br />
-1<br />
GetCount()<br />
GetItemLabel(n)<br />
SetItemLabel(n, str<strong>in</strong>g)n<br />
GetSelection()<br />
GetStr<strong>in</strong>gSelection()<br />
SetSelection(n)<br />
SetStr<strong>in</strong>gSelection( str<strong>in</strong>g)GetSelection() SetSelection()<br />
GetStr<strong>in</strong>gSelection()<br />
208 / 565
SetStr<strong>in</strong>gSelection()set*()<br />
EVT_RADIOBOX<br />
ShowItem(item, show)showitem<br />
<br />
<br />
<br />
7.4.3 <br />
<br />
<br />
<br />
7.13<br />
<strong>wxPython</strong><br />
<strong>wxPython</strong>wx.ListBox<br />
<br />
<br />
7.137.13<br />
7.13 wx.ListBox<br />
import wx<br />
class ListBoxFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
209 / 565
wx.Frame.__<strong>in</strong>it__(self, None, -1, ’List Box Example’,<br />
size=(250, 200))<br />
panel = wx.Panel(self, -1)<br />
sampleList = [‘zero’, ’one’, ’two’, ’three’, ’four’, ’five’,<br />
’six’, ’seven’, ’eight’, ’n<strong>in</strong>e’, ’ten’, ’eleven’,<br />
’twelve’, ’thirteen’, ’fourteen’]<br />
listBox = wx.ListBox(panel, -1, (20, 20), (80, 120), sampleList,<br />
wx.LB_SINGLE)<br />
listBox.SetSelection(3)<br />
if __name__ == ’__ma<strong>in</strong>__’:<br />
app = wx.PySimpleApp()<br />
ListBoxFrame().Show()<br />
app.Ma<strong>in</strong>Loop()<br />
wx.ListBox<br />
wx.ListBox(parent, id, pos=wx.DefaultPosition,<br />
size=wx.DefaultSize, choices=None, style=0,<br />
validator=wx.DefaultValidator, name=”listBox”)<br />
wx.ListBoxlabel<br />
choices<br />
7.12<br />
<br />
<br />
<br />
<br />
7.12 <br />
wx.LB_EXTENDEDshift<br />
<br />
wx.LB_MULTIPLE<br />
<br />
210 / 565
wx.LB_SINGLE<br />
<br />
wx.ListBox7.13<br />
7.13 <br />
wx.LB_ALWAYS_SB<br />
wx.LB_HSCROLL<br />
<br />
wx.LB_HSCROLL<br />
wx.LB_SORT<br />
wx.ListBoxEVT_LISTBOX<br />
<br />
EVT_LISTBOX_DCLICK<br />
7.14<br />
0<br />
<br />
<br />
7.14 <br />
Append(item)<br />
Clear()<br />
Delete(n)n<br />
Deselect(n)n<br />
<br />
F<strong>in</strong>dStr<strong>in</strong>g(str<strong>in</strong>g)-1<br />
GetCount()<br />
GetSelection()<br />
SetSelection(n, select)<br />
211 / 565
GetStr<strong>in</strong>gSelection()<br />
SetStr<strong>in</strong>gSelection(str<strong>in</strong>g, select)<br />
GetSelections()GetSelection()<br />
GetSelections()<br />
GetStr<strong>in</strong>gSelection()set<br />
select<br />
EVT_LISTBOX<br />
GetStr<strong>in</strong>g(n)<br />
SetStr<strong>in</strong>g(n, str<strong>in</strong>g)n<br />
InsertItems(items, pos)itemspos<br />
0<br />
Selected(n)n<br />
Set(choices)choices<br />
7.4.4 <br />
wx.CheckListBox7.14<br />
<br />
7.14<br />
wx.CheckListBoxwx.ListBox<br />
wx.EVT_CHECKLISTBOX<br />
Check(n, check)n<br />
IsChecked(item)True<br />
212 / 565
7.4.5 <br />
<br />
<br />
7.157.16<br />
7.15<br />
7.16<br />
7.14<br />
<br />
7.14<br />
import wx<br />
class ChoiceFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, -1, ’Choice Example’,<br />
size=(250, 200))<br />
panel = wx.Panel(self, -1)<br />
sampleList = [‘zero’, ’one’, ’two’, ’three’, ’four’, ’five’,<br />
’six’, ’seven’, ’eight’]<br />
wx.StaticText(panel, -1, ”Select one:”, (15, 20))<br />
213 / 565
wx.Choice(panel, -1, (85, 18), choices=sampleList)<br />
if __name__ == ’__ma<strong>in</strong>__’:<br />
app = wx.PySimpleApp()<br />
ChoiceFrame().Show()<br />
app.Ma<strong>in</strong>Loop()<br />
wx.Choice<br />
wx.Choice(parent, id, pos=wx.DefaultPosition,<br />
size=wx.DefaultSize, choices=None, style=0,<br />
validator=wx.DefaultValidator, name=”choice”)<br />
wx.ChoiceEVT_CHOICE<br />
7.14wx.Choice<br />
7.4.6 <br />
<br />
7.17<br />
7.17 wx.CB_DropDOWNwx.CB_SIMPLE<br />
W<strong>in</strong>dows<br />
<br />
214 / 565
wx.ComboBoxwx.Choice7.157.17<br />
7.15<br />
import wx<br />
class ComboBoxFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, -1, ’Combo Box Example’,<br />
size=(350, 300))<br />
panel = wx.Panel(self, -1)<br />
sampleList = [‘zero’, ’one’, ’two’, ’three’, ’four’, ’five’,<br />
’six’, ’seven’, ’eight’]<br />
wx.StaticText(panel, -1, ”Select one:”, (15, 15))<br />
wx.ComboBox(panel, -1, ”default value”, (15, 30), wx.DefaultSize,<br />
sampleList, wx.CB_DropDOWN)<br />
wx.ComboBox(panel, -1, ”default value”, (150, 30), wx.DefaultSize,<br />
sampleList, wx.CB_SIMPLE)<br />
if __name__ == ’__ma<strong>in</strong>__’:<br />
app = wx.PySimpleApp()<br />
ComboBoxFrame().Show()<br />
app.Ma<strong>in</strong>Loop()<br />
wx.ComboBox<br />
wx.ComboBox(parent, id, value=””, pos=wx.DefaultPosition,<br />
size=wx.DefaultSize, choices, style=0,<br />
validator=wx.DefaultValidator, name=”comboBox”)<br />
wx.ComboBox4<br />
wx.CB_DropDOWNwx.CB_SIMPLE<br />
W<strong>in</strong>dowswx.CB_SIMPLE<br />
wx.CB_READONLY<br />
<br />
wx.CB_SORT<br />
<br />
215 / 565
wx.ComboBoxwx.Choicewx.Choice<br />
7.14<br />
wx.TextCtrl7.4)<br />
Copy(), Cut(), GetInsertionPo<strong>in</strong>t(), GetValue(), Paste(), Replace(from,to, text), Remo<br />
ve(from, to), SetInsertionPo<strong>in</strong>t(pos), SetInsertionPo<strong>in</strong>tEnd(), SetValue()<br />
7.5 <br />
<strong>wxPython</strong><br />
<br />
1wx.StaticText<br />
<strong>wxPython</strong>wx.lib.stattext.GenStaticText<br />
2wx.TextCtrl<br />
<br />
wx.TextCtrlwx.Text-Attrwx.Font<br />
wx.stc.StyledTextCtrl<br />
<strong>wxPython</strong>Sc<strong>in</strong>tilla<br />
<br />
3wx.Button<br />
wx.lib.buttons.GenButton<br />
wx.BitmapButton<br />
<br />
4wx.Slider<br />
wx.Sp<strong>in</strong>Ctrl<br />
wx.Gauge<br />
5<br />
<br />
wx.CheckBox<br />
wx.RadioButtonwx.RadioBox<br />
<br />
wx.ListBoxwx.CheckListBox<br />
wx.Choice. wx.ComboBox<br />
216 / 565
217 / 565
8<br />
<strong>wxPython</strong><br />
<strong>wxPython</strong> <br />
<strong>wxPython</strong>wx.Frame<br />
wx.Frame<strong>wxPython</strong><br />
<br />
panel<br />
8.1 <br />
<br />
<br />
<br />
8.1.1 <br />
<br />
<br />
<br />
wx.Frame8.1<br />
8.1 wx.Frame<br />
import wx<br />
if __name__ == ’__ma<strong>in</strong>__’:<br />
app = wx.PySimpleApp()<br />
frame = wx.Frame(None, -1, ”A Frame”, style=wx.DEFAULT_FRAME_STYLE<br />
,<br />
size=(200, 100))<br />
frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
(200,100)8.1<br />
8.1<br />
218 / 565
8.1<br />
wx.Frame7<br />
<br />
wx.Frame(parent, id=-1, title=””, pos=wx.DefaultPosition,<br />
size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE,<br />
name=”frame”)<br />
wx.Frame<br />
<br />
<br />
wx.Framewx.Frame<br />
<br />
<br />
<br />
wx.Frame<br />
<strong>wxPython</strong>wx.Frame<br />
wx.Frame——<br />
<br />
<br />
8.2wx.Frame<br />
8.2 <br />
import wx<br />
class SubclassFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, -1, ’Frame Subclass’,<br />
size=(300, 100))<br />
219 / 565
panel = wx.Panel(self, -1)<br />
button = wx.Button(panel, -1, ”Close Me”, pos=(15, 15))<br />
self.B<strong>in</strong>d(wx.EVT_BUTTON, self.OnCloseMe, button)<br />
self.B<strong>in</strong>d(wx.EVT_CLOSE, self.OnCloseW<strong>in</strong>dow)<br />
def OnCloseMe(self, event):<br />
self.Close(True)<br />
def OnCloseW<strong>in</strong>dow(self, event):<br />
self.Destroy()<br />
if __name__ == ’__ma<strong>in</strong>__’:<br />
app = wx.PySimpleApp()<br />
SubclassFrame().Show()<br />
app.Ma<strong>in</strong>Loop()<br />
8.2<br />
8.2<br />
<br />
wx.Frame.__<strong>in</strong>it__wx.Frame<br />
self<br />
<br />
<br />
panel<br />
panel)wx.Panel<br />
wx.Panel<br />
<br />
wx.Panel<br />
MS W<strong>in</strong>dowswx.Panel<br />
panel<br />
220 / 565
panel<br />
tab<br />
8.1.2 <br />
wx.Frame<br />
<br />
——<br />
8.1<br />
8.1 <br />
wx.FRAME_NO_TASKBARW<strong>in</strong>dows<br />
<br />
<br />
wx.FRAME_SHAPEDSetShape()<br />
<br />
wx.FRAME_TOOL_WINDOW<br />
W<strong>in</strong>dows<br />
wx.ICONIZEW<strong>in</strong>dows<br />
wx.MAXIMIZEW<strong>in</strong>dows<br />
<br />
wx.MINIMIZEwx.ICONIZE<br />
<br />
wx.FRAME_TOOL_WINDOW8.3<br />
wx.FRAME_TOOL_WINDOWwx.CAPTIONwx.SYSTEM_MENU<br />
<br />
8.3<br />
221 / 565
8.2<br />
<br />
8.3<br />
<br />
8.2 <br />
wx.FRAME_FLOAT_ON_PARENT<br />
<br />
<br />
wx.STAY_ON_TOP<br />
<br />
<br />
wx.DEFAULT_FRAME_STYLE<br />
wx.MINIMIZE_BOX | wx.MAXIMIZE_BOX | wx.CLOSE_BOX | wx.RESIZE_BO<br />
RDER | wx.SYSTEM_MENU |wx.CAPTION<br />
<br />
<br />
<br />
style=wx.DEFAULT_FRAME_STYLE | wx.FRAME_TOOL_WINDOW<br />
^<br />
8.3 <br />
wx.CAPTION<br />
<br />
wx.FRAME_EX_CONTEXTHELPW<strong>in</strong>dows<br />
wx.MAXIMIZE_BOXWX.MINIMIZE_BOX<br />
<br />
wx.FRAME_EX_METALMac OS X<br />
SetExtraStyle<br />
wx.MAXIMIZE_BOX<br />
wx.MINIMIZE_BOX<br />
222 / 565
wx.CLOSE_BOX<br />
wx.RESIZE_BORDER<br />
wx.SIMPLE_BORDER<br />
<br />
wx.SYSTEM_MENU<br />
wx.MINIMIZE_BOX<br />
“”<br />
8.1.3 <br />
wx.FRAME_EX_CONTEXTHELP<br />
C++<br />
SetExtraStyle<br />
wx.FRAME_EX_CONTEXTHELP<br />
UI<strong>wxPython</strong><br />
<br />
8.4<br />
8.4<br />
SetExtraStyle()<br />
<br />
<br />
<br />
<strong>wxPython</strong>wx.PreFrame<br />
preframe<br />
preframe8.3<br />
two-step<br />
<strong>wxPython</strong>C++ wxWidgetstwostep<br />
223 / 565
8.3<br />
import wx<br />
class HelpFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
pre = wx.PreFrame() #1 <br />
pre.SetExtraStyle(wx.FRAME_EX_CONTEXTHELP)<br />
pre.Create(None, -1, ”Help Context”, size=(300, 100),<br />
style=wx.DEFAULT_FRAME_STYLE ^<br />
(wx.MINIMIZE_BOX | wx.MAXIMIZE_BOX)) #2 <br />
self.PostCreate(pre) #3 C++<br />
if __name__ == ’__ma<strong>in</strong>__’:<br />
app = wx.PySimpleApp()<br />
HelpFrame().Show()<br />
app.Ma<strong>in</strong>Loop()<br />
#1 wx.PreFrame()<br />
wx.PreDialog()——wxWidgets<br />
<br />
#2 Create()<br />
#3 <strong>wxPython</strong>C++PostCreate<br />
C++<br />
<br />
<br />
8.4<br />
Python<br />
Python__<strong>in</strong>it__<br />
8.4 <br />
def twoStepCreate(<strong>in</strong>stance, preClass, preInitFunc, *args,<br />
**kwargs):<br />
224 / 565
pre = preClass()<br />
preInitFunc(pre)<br />
pre.Create(*args, **kwargs)<br />
<strong>in</strong>stance.PostCreate(pre)<br />
8.4<strong>in</strong>stance<br />
preClass——<br />
wx.PreFramepreInitFunc<br />
<br />
pre = preClass()<br />
preInitFunc<br />
pre.Create()<br />
PostCreatepre<br />
<strong>in</strong>stancetwoStepCreate<br />
8.5<br />
8.5 <br />
import wx<br />
class HelpFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self, parent, ID, title,<br />
pos=wx.DefaultPosition, size=(100,100),<br />
style=wx.DEFAULT_DIALOG_STYLE):<br />
twoStepCreate(self, wx.PreFrame, self.preInit, parent,<br />
id, title, pos, size, style)<br />
def preInit(self, pre):<br />
pre.SetExtraStyle(wx.FRAME_EX_CONTEXTHELP)<br />
wx.PreFrameself.preInitpreInit<br />
<br />
8.1.4 <br />
<br />
<strong>wxPython</strong><br />
<br />
225 / 565
<strong>wxPython</strong><br />
<br />
C++ wxWidgetsC++<br />
<strong>wxPython</strong><br />
<br />
“”“”——<br />
<br />
<br />
<br />
Close<br />
<strong>wxPython</strong>EVT_CLOSE<strong>wxPython</strong> <br />
EVT_CLOSE<br />
<br />
<br />
<br />
1Destroy()<br />
<br />
2——<br />
<br />
<br />
Destroy()<br />
<br />
Destroy()<br />
Destroy()Close()Close()<br />
<br />
<br />
wx.CloseEvent.Veto()<br />
<br />
<br />
<br />
Close()<br />
226 / 565
Destroy()<br />
<br />
<br />
<br />
wx.App EVT_QUERY_END_SESSION<br />
<br />
GUIEVT_END_SESSION<br />
<br />
Destroy()<br />
<br />
<br />
<br />
<br />
8.2 <br />
<br />
<br />
8.2.1 wx.Frame<br />
wx.Framewx.W<strong>in</strong>dow<br />
8.4<br />
wx.Frame<br />
8.4 wx.Frame<br />
GetBackgroundColor()<br />
SetBackgroundColor(wx.Color)<br />
wx.Color<br />
<strong>wxPython</strong>wx.NamedColour()<br />
GetId()<br />
SetId(<strong>in</strong>t)<br />
GetMenuBar()<br />
227 / 565
SetMenuBar(wx.MenuBar)<br />
None<br />
GetPosition()<br />
GetPositionTuple()<br />
SetPosition(wx.Po<strong>in</strong>t)wx.Po<strong>in</strong>tPythonx,y<br />
<br />
<br />
GetSize()<br />
GetSizeTuple()<br />
SetSize(wx.Size)C++get*set*get*set*<br />
wx.SizeGetSizeTuple()Python<br />
SetDimensions()<br />
GetTitle()<br />
SetTitle(Str<strong>in</strong>g)<br />
8.5wx.Frame<br />
Refresh()<br />
8.5 wx.Frame<br />
Center(direction=wx.BOTH)Centre<br />
wx.BoTH<br />
wx.HORIZONTALwx.VERTICAL<br />
Enable(enable=true)true<br />
FalseDisable()<br />
GetBestSize()wx.Frame<br />
Iconize(iconize)true<br />
False<br />
IsEnabled()True<br />
IsFullScreen()TrueFalse<br />
ShowFullScreen<br />
IsIconized()TrueFalse<br />
IsMaximized()TrueFalse<br />
228 / 565
IsShown()True<br />
IsTopLevel()True<br />
False<br />
Maximize(maximize)True<br />
<br />
<br />
Refresh(erase"242.files/">rect=None)rectnone<br />
<br />
eraseBackgroundTrueFalse<br />
<br />
SetDimensions(x, y, width, height,sizeFlags=wx.SIZE_AUTO)<br />
xywidthheight<br />
-1-1sizeFlags<br />
8.6sizeFlags<br />
Show(show=True)TrueFalse<br />
Show(False)Hide()<br />
ShowFullScreen(show,style=wx.FULLSCREEN_ALL)True<br />
——<br />
Falsestyle<br />
wx.FULLSCREEN_ALL<strong>wxPython</strong><br />
<br />
<br />
wx.FULLSCREEN_NOBORDER, wx.FULLSCREEN_NOCAPTION,wx.FULLSCRE<br />
EN_NOMENUBAR,wx.FULLSCREEN_NOSTATUSBAR,wx.FULLSCREEN_NOTO<br />
OLBAR<br />
8.5SetDimensions()-1<br />
8.6<br />
<br />
<br />
8.6 SetDimensions<br />
wx.ALLOW_MINUS_ONE<br />
wx.SIZE_AUTO<strong>wxPython</strong><br />
229 / 565
wx.SIZE_AUTO_HEIGHT<strong>wxPython</strong><br />
wx.SIZE_AUTO_WIDTH<strong>wxPython</strong><br />
wx.SIZE_USE_EXISTING<br />
8.2.2 <br />
(panel)<br />
6<br />
<br />
<br />
<br />
8.6<br />
7F<strong>in</strong>dItemById()<br />
ID<br />
8.6 ID<br />
def OnColor(self, event):<br />
menubar = self.GetMenuBar()<br />
itemId = event.GetId()<br />
item = menubar.F<strong>in</strong>dItemById(itemId)<br />
color = item.GetLabel()<br />
self.sketch.SetColor(color)<br />
<strong>wxPython</strong><br />
<br />
(panel)<strong>wxPython</strong> ID<br />
name<br />
<br />
<br />
1wx.F<strong>in</strong>dW<strong>in</strong>dowById(id, parent=None)<br />
2wx.F<strong>in</strong>dW<strong>in</strong>dowByName(name, parent=None)<br />
3wx.F<strong>in</strong>dW<strong>in</strong>dowByLabel(label, parent=None)<br />
230 / 565
parent<br />
F<strong>in</strong>dF<strong>in</strong>dW<strong>in</strong>dowByName()<br />
nameF<strong>in</strong>dW<strong>in</strong>dowByLabel()<br />
<br />
8.2.3 <br />
<strong>wxPython</strong><br />
wx.ScrolledW<strong>in</strong>dowwx.Panel<br />
wx.ScrolledW<strong>in</strong>dow8.58.6<br />
8.58.6<br />
<br />
<br />
<br />
8.5<br />
8.6<br />
231 / 565
8.7<br />
8.7 <br />
import wx<br />
class ScrollbarFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, -1, ’Scrollbar Example’,<br />
size=(300, 200))<br />
self.scroll = wx.ScrolledW<strong>in</strong>dow(self, -1)<br />
self.scroll.SetScrollbars(1, 1, 600, 400)<br />
self.button = wx.Button(self.scroll, -1, ”Scroll Me”, pos=(50, 20))<br />
self.B<strong>in</strong>d(wx.EVT_BUTTON, self.OnClickTop, self.button)<br />
self.button2 = wx.Button(self.scroll, -1, ”Scroll Back”, pos=(500, 350))<br />
self.B<strong>in</strong>d(wx.EVT_BUTTON, self.OnClickBottom, self.button2)<br />
def OnClickTop(self, event):<br />
self.scroll.Scroll(600, 400)<br />
def OnClickBottom(self, event):<br />
self.scroll.Scroll(1, 1)<br />
if __name__ == ’__ma<strong>in</strong>__’:<br />
app = wx.PySimpleApp()<br />
frame = ScrollbarFrame()<br />
frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
wx.ScrolledW<strong>in</strong>dowwx.Panel<br />
wx.ScrolledW<strong>in</strong>dow(parent, id=-1, pos=wx.DefaultPosition,<br />
size=wx.DefaultSize, style=wx.HSCROLL | wx.VSCROLL,<br />
name=”scrolledW<strong>in</strong>dow”)<br />
size<br />
<br />
232 / 565
8.1<br />
SetScrollBars<br />
SetScrollbars(pixelsPerUnitX, pixelsPerUnitY, noUnitsX, noUnitsY,<br />
xPos=0, yPos=0, noRefresh=False)<br />
<br />
pixelsPerUnitXPixelsPerUnitY<br />
noUnitsXnoUnitsY<br />
<br />
(pixelsPerUnitX* noUnitsX, pixelsPerUnitY * noUnitsY)8.7<br />
1xPosyPos<br />
noRefreshtrue<br />
SetScrollbars()<br />
<br />
<br />
SetVirtualSize()<br />
<br />
self.scroll.SetVirtualSize((600, 400))<br />
FitInside()<br />
<br />
<br />
self.scroll.FitInside()<br />
FitInside()<br />
8.7<br />
FitInside()<br />
<br />
sizerSetSizer()<br />
sizer<br />
sizer11<br />
233 / 565
SetScrollRate()<br />
<br />
self.scroll.SetScrollRate(1, 1)<br />
xy0<br />
<br />
8.7Scroll()<br />
xy<br />
7<br />
8.7<br />
<br />
8.7 <br />
EVT_SCROLL<br />
EVT_SCROLL_BOTTOM<br />
<br />
EVT_SCROLL_ENDSCROLLW<strong>in</strong>dows<br />
<br />
EVT_SCROLL_LINEDOWN<br />
EVT_SCROLL_LINEUP<br />
EVT_SCROLL_PAGEDOWN<br />
EVT_SCROLL_PAGEUP<br />
EVT_SCROLL_THUMBRELEASE<br />
<br />
EVT_SCROLL_THUMBTRACK<br />
EVT_SCROLL_TOP<br />
<br />
234 / 565
EVT_SCROLL*EVT_SCROLLWIN*<br />
wx.ScrolledW<strong>in</strong>dow<br />
<strong>wxPython</strong><br />
wx.lib.scrolledpanel.ScrolledPanel<br />
sizerwx.lib.scrolledpanel.ScrolledPanel<br />
tab<br />
<br />
wx.lib.scrolledpanel.ScrolledPanel<br />
<br />
SetupScroll<strong>in</strong>g(self, scroll_x=True, scroll_y=True, rate_x=20,<br />
rate_y=20)<br />
rate_xrate_ysizer<br />
(virtual size)<br />
<br />
<br />
(virtual size)<br />
8.5Scroll Me<br />
(-277,-237)CalcScrolledPosition(x,y)<br />
CalcUnscrolledPosition(x, y)<br />
<br />
(x,y)<br />
CalcUnscrolledPostion(-277, -237) (50, 20)<br />
8.3 <br />
<br />
MDI<br />
<br />
8.3.1 MDI<br />
MDIMDI90<br />
<br />
235 / 565
MDI<br />
z<br />
MDI<br />
8.7MDI<br />
<strong>wxPython</strong>MDIW<strong>in</strong>dows<br />
MDIMDI8.8<br />
MDI<br />
<br />
8.8 MDI<br />
import wx<br />
class MDIFrame(wx.MDIParentFrame):<br />
def __<strong>in</strong>it__(self):<br />
wx.MDIParentFrame.__<strong>in</strong>it__(self, None, -1, ”MDI Parent”,<br />
size=(600,400))<br />
menu = wx.Menu()<br />
menu.Append(5000, ”&New W<strong>in</strong>dow”)<br />
menu.Append(5001, ”E&xit”)<br />
menubar = wx.MenuBar()<br />
menubar.Append(menu, ”&File”)<br />
self.SetMenuBar(menubar)<br />
236 / 565
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnNewW<strong>in</strong>dow, id=5000)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnExit, id=5001)<br />
def OnExit(self, evt):<br />
self.Close(True)<br />
def OnNewW<strong>in</strong>dow(self, evt):<br />
w<strong>in</strong> = wx.MDIChildFrame(self, -1, ”Child W<strong>in</strong>dow”)<br />
w<strong>in</strong>.Show(True)<br />
if __name__ == ’__ma<strong>in</strong>__’:<br />
app = wx.PySimpleApp()<br />
frame = MDIFrame()<br />
frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
MDIwx.MDIParentFrame<br />
<strong>wxPython</strong><br />
wx.MDIChildFramewx.MDIParentFramewx.Frame<br />
<br />
wx.MDIParentFrame(parent, id, title, pos = wx.DefaultPosition,<br />
size=wxDefaultSize,<br />
style=wx.DEFAULT_FRAME_STYLE | wx.VSCROLL | wx.HSCROLL,<br />
name=”frame”)<br />
wx.MDIParentFrame<br />
wx.MDIChildFrame8.8<br />
<br />
Cascade()Tile()<br />
Cascade()<br />
8.7Tile()<br />
<br />
ActivateNext()ActivatePrevious()<br />
237 / 565
8.3.2 <br />
<br />
W<strong>in</strong>dowsGTK8.8<br />
<br />
8.8 <br />
<br />
wx.M<strong>in</strong>iFrame8.9<br />
8.9 <br />
import wx<br />
class M<strong>in</strong>iFrame(wx.M<strong>in</strong>iFrame):<br />
def __<strong>in</strong>it__(self):<br />
wx.M<strong>in</strong>iFrame.__<strong>in</strong>it__(self, None, -1, ’M<strong>in</strong>i Frame’,<br />
size=(300, 100))<br />
panel = wx.Panel(self, -1, size=(300, 100))<br />
button = wx.Button(panel, -1, ”Close Me”, pos=(15, 15))<br />
self.B<strong>in</strong>d(wx.EVT_BUTTON, self.OnCloseMe, button)<br />
self.B<strong>in</strong>d(wx.EVT_CLOSE, self.OnCloseW<strong>in</strong>dow)<br />
def OnCloseMe(self, event):<br />
self.Close(True)<br />
def OnCloseW<strong>in</strong>dow(self, event):<br />
self.Destroy()<br />
if __name__ == ’__ma<strong>in</strong>__’:<br />
app = wx.PySimpleApp()<br />
M<strong>in</strong>iFrame().Show()<br />
238 / 565
app.Ma<strong>in</strong>Loop()<br />
wx.M<strong>in</strong>iFramewx.Framewx.M<strong>in</strong>iFrame<br />
8.8<br />
8.8 wx.M<strong>in</strong>iFrame<br />
wx.THICK_FRAMEW<strong>in</strong>dowsMotif<br />
wx.TINY_CAPTION_HORIZONTALwx.CAPTION<br />
<br />
wx.TINY_CAPTION_VERTICALwx.CAPTION<br />
<br />
<br />
<br />
8.3.3 <br />
<br />
<br />
<strong>wxPython</strong><br />
<br />
8.9<br />
<br />
<br />
<strong>wxPython</strong> demoimagesvippi<br />
<strong>wxPython</strong><br />
239 / 565
8.9<br />
8.10<br />
<br />
<br />
8.10 <br />
import wx<br />
import images<br />
class ShapedFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, -1, ”Shaped W<strong>in</strong>dow”,<br />
style = wx.FRAME_SHAPED | wx.SIMPLE_BORDER |<br />
wx.FRAME_NO_TASKBAR)<br />
self.hasShape = False<br />
#1 <br />
self.bmp = images.getVippiBitmap()<br />
self.SetClientSize((self.bmp.GetWidth(), self.bmp.GetHeight()))<br />
#2 <br />
dc = wx.ClientDC(self)<br />
dc.DrawBitmap(self.bmp, 0,0, True)<br />
240 / 565
self.SetW<strong>in</strong>dowShape()<br />
self.B<strong>in</strong>d(wx.EVT_LEFT_DCLICK, self.OnDoubleClick)<br />
self.B<strong>in</strong>d(wx.EVT_RIGHT_UP, self.OnExit)<br />
self.B<strong>in</strong>d(wx.EVT_PAINT, self.OnPa<strong>in</strong>t)<br />
self.B<strong>in</strong>d(wx.EVT_WINDOW_Create, self.SetW<strong>in</strong>dowShape)#3 <br />
<br />
def SetW<strong>in</strong>dowShape(self, evt=None):#4 <br />
r = wx.RegionFromBitmap(self.bmp)<br />
self.hasShape = self.SetShape(r)<br />
def OnDoubleClick(self, evt):<br />
if self.hasShape:<br />
self.SetShape(wx.Region())#5 <br />
self.hasShape = False<br />
else:<br />
self.SetW<strong>in</strong>dowShape()<br />
def OnPa<strong>in</strong>t(self, evt):<br />
dc = wx.Pa<strong>in</strong>tDC(self)<br />
dc.DrawBitmap(self.bmp, 0,0, True)<br />
def OnExit(self, evt):<br />
self.Close()<br />
if __name__ == ’__ma<strong>in</strong>__’:<br />
app = wx.PySimpleApp()<br />
ShapedFrame().Show()<br />
app.Ma<strong>in</strong>Loop()<br />
#1 images<br />
<strong>wxPython</strong>16<br />
<br />
#2 <br />
<br />
<br />
#3 <br />
SetW<strong>in</strong>dowShape()GTK<br />
241 / 565
UI<br />
<br />
#4 wx.RegionFromBitmap<br />
wx.Region<br />
wx.Region<br />
<br />
#5 <br />
wx.RegionSetShape()<br />
<br />
SetShape()wx.Frame<br />
wx.SplashScreen<br />
<br />
8.3.4 <br />
<br />
<br />
8.11<br />
<br />
<br />
8.11 <br />
import wx<br />
import images<br />
class ShapedFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, -1, ”Shaped W<strong>in</strong>dow”,<br />
style = wx.FRAME_SHAPED | wx.SIMPLE_BORDER )<br />
self.hasShape = False<br />
self.delta = wx.Po<strong>in</strong>t(0,0)<br />
self.bmp = images.getVippiBitmap()<br />
self.SetClientSize((self.bmp.GetWidth(), self.bmp.GetHeight()))<br />
dc = wx.ClientDC(self)<br />
dc.DrawBitmap(self.bmp, 0,0, True)<br />
self.SetW<strong>in</strong>dowShape()<br />
242 / 565
self.B<strong>in</strong>d(wx.EVT_LEFT_DCLICK, self.OnDoubleClick)<br />
#1 <br />
self.B<strong>in</strong>d(wx.EVT_LEFT_DOWN, self.OnLeftDown)<br />
self.B<strong>in</strong>d(wx.EVT_LEFT_UP, self.OnLeftUp)<br />
self.B<strong>in</strong>d(wx.EVT_MOTION, self.OnMouseMove)<br />
self.B<strong>in</strong>d(wx.EVT_RIGHT_UP, self.OnExit)<br />
self.B<strong>in</strong>d(wx.EVT_PAINT, self.OnPa<strong>in</strong>t)<br />
self.B<strong>in</strong>d(wx.EVT_WINDOW_Create, self.SetW<strong>in</strong>dowShape)<br />
def SetW<strong>in</strong>dowShape(self, evt=None):<br />
r = wx.RegionFromBitmap(self.bmp)<br />
self.hasShape = self.SetShape(r)<br />
def OnDoubleClick(self, evt):<br />
if self.hasShape:<br />
self.SetShape(wx.Region())<br />
self.hasShape = False<br />
else:<br />
self.SetW<strong>in</strong>dowShape()<br />
def OnPa<strong>in</strong>t(self, evt):<br />
dc = wx.Pa<strong>in</strong>tDC(self)<br />
dc.DrawBitmap(self.bmp, 0,0, True)<br />
def OnExit(self, evt):<br />
self.Close()<br />
def OnLeftDown(self, evt):#2 <br />
self.CaptureMouse()<br />
pos = self.ClientToScreen(evt.GetPosition())<br />
orig<strong>in</strong> = self.GetPosition()<br />
self.delta = wx.Po<strong>in</strong>t(pos.x - orig<strong>in</strong>.x, pos.y - orig<strong>in</strong>.y)<br />
def OnMouseMove(self, evt):#3 <br />
if evt.Dragg<strong>in</strong>g() and evt.LeftIsDown():<br />
pos = self.ClientToScreen(evt.GetPosition())<br />
newPos = (pos.x - self.delta.x, pos.y - self.delta.y)<br />
self.Move(newPos)<br />
243 / 565
def OnLeftUp(self, evt):#4 <br />
if self.HasCapture():<br />
self.ReleaseMouse()<br />
if __name__ == ’__ma<strong>in</strong>__’:<br />
app = wx.PySimpleApp()<br />
ShapedFrame().Show()<br />
app.Ma<strong>in</strong>Loop()<br />
#1 <br />
<br />
#2 <br />
<br />
<br />
<br />
#3 <br />
<br />
<br />
#4 ReleaseMouse()<br />
<br />
<br />
<br />
<br />
8.4 <br />
<br />
<br />
<br />
8.10<br />
244 / 565
Mac OS X F<strong>in</strong>der<br />
<br />
8.4.1 <br />
<strong>wxPython</strong>wx.SplitterW<strong>in</strong>dow<br />
<strong>wxPython</strong><br />
<br />
8.10<br />
wx.SplitterW<strong>in</strong>dow(parent, id=-1, pos=wx.DefaultPosition,<br />
size=wx.DefaultSize, style=wx.SP_3D,<br />
name=”splitterW<strong>in</strong>dow”)<br />
——parentpos<br />
size<br />
245 / 565
Initialize(w<strong>in</strong>dow)w<strong>in</strong>dowwx.Panel<br />
<br />
<br />
SplitHorizontally (w<strong>in</strong>dow1w<strong>in</strong>dow2sashPosition=0)<br />
SplitVertically(w<strong>in</strong>dow1, w<strong>in</strong>dow2, sashPosition=0)<br />
w<strong>in</strong>dow1w<strong>in</strong>dow2sashPosition<br />
w<strong>in</strong>dow1w<strong>in</strong>dow2<br />
sashPosition<br />
sashPosition<br />
sashPosition0<br />
w<strong>in</strong>dow1w<strong>in</strong>dow2<br />
sashPositionw<strong>in</strong>dow1<br />
sashPosition0<br />
sizer<br />
<br />
8.4.2 <br />
8.12<br />
<br />
Hide()<br />
<br />
<br />
<br />
8.12 <br />
import wx<br />
class SplitterExampleFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self, parent, title):<br />
wx.Frame.__<strong>in</strong>it__(self, parent, title=title)<br />
self.MakeMenuBar()<br />
self.m<strong>in</strong>pane = 0<br />
self.<strong>in</strong>itpos = 0<br />
self.sp = wx.SplitterW<strong>in</strong>dow(self)# <br />
self.p1 = wx.Panel(self.sp, style=wx.SUNKEN_BORDER)# <br />
246 / 565
self.p2 = wx.Panel(self.sp, style=wx.SUNKEN_BORDER)<br />
self.p1.SetBackgroundColour(“p<strong>in</strong>k”)<br />
self.p2.SetBackgroundColour(“sky blue”)<br />
self.p1.Hide()# <br />
self.p2.Hide()<br />
self.sp.Initialize(self.p1)# <br />
self.B<strong>in</strong>d(wx.EVT_SPLITTER_SASH_POS_CHANGING,<br />
self.OnSashChang<strong>in</strong>g, self.sp)<br />
self.B<strong>in</strong>d(wx.EVT_SPLITTER_SASH_POS_CHANGED,<br />
self.OnSashChanged, self.sp)<br />
def MakeMenuBar(self):<br />
menu = wx.Menu()<br />
item = menu.Append(-1, ”Split horizontally”)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnSplitH, item)<br />
self.B<strong>in</strong>d(wx.EVT_Update_UI, self.OnCheckCanSplit, item)<br />
item = menu.Append(-1, ”Split vertically”)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnSplitV, item)<br />
self.B<strong>in</strong>d(wx.EVT_Update_UI, self.OnCheckCanSplit, item)<br />
item = menu.Append(-1, ”Unsplit”)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnUnsplit, item)<br />
self.B<strong>in</strong>d(wx.EVT_Update_UI, self.OnCheckCanUnsplit, item)<br />
menu.AppendSeparator()<br />
item = menu.Append(-1, ”Set <strong>in</strong>itial sash position”)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnSetPos, item)<br />
item = menu.Append(-1, ”Set m<strong>in</strong>imum pane size”)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnSetM<strong>in</strong>, item)<br />
menu.AppendSeparator()<br />
item = menu.Append(wx.ID_EXIT, ”E&xit”)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnExit, item)<br />
mbar = wx.MenuBar()<br />
mbar.Append(menu, ”Splitter”)<br />
self.SetMenuBar(mbar)<br />
247 / 565
def OnSashChang<strong>in</strong>g(self, evt):<br />
pr<strong>in</strong>t ”OnSashChang<strong>in</strong>g:”, evt.GetSashPosition()<br />
def OnSashChanged(self, evt):<br />
pr<strong>in</strong>t ”OnSashChanged:”, evt.GetSashPosition()<br />
def OnSplitH(self, evt):# <br />
self.sp.SplitHorizontally(self.p1, self.p2, self.<strong>in</strong>itpos)<br />
def OnSplitV(self, evt):# <br />
self.sp.SplitVertically(self.p1, self.p2, self.<strong>in</strong>itpos)<br />
def OnCheckCanSplit(self, evt):<br />
evt.Enable(not self.sp.IsSplit())<br />
def OnCheckCanUnsplit(self, evt):<br />
evt.Enable(self.sp.IsSplit())<br />
def OnUnsplit(self, evt):<br />
self.sp.Unsplit()<br />
def OnSetM<strong>in</strong>(self, evt):<br />
m<strong>in</strong>pane = wx.GetNumberFromUser(<br />
”Enter the m<strong>in</strong>imum pane size”,<br />
””, ”M<strong>in</strong>imum Pane Size”, self.m<strong>in</strong>pane,<br />
0, 1000, self)<br />
if m<strong>in</strong>pane != -1:<br />
self.m<strong>in</strong>pane = m<strong>in</strong>pane<br />
self.sp.SetM<strong>in</strong>imumPaneSize(self.m<strong>in</strong>pane)<br />
def OnSetPos(self, evt):<br />
<strong>in</strong>itpos = wx.GetNumberFromUser(<br />
”Enter the <strong>in</strong>itial sash position (to be used <strong>in</strong> the Split call)”,<br />
””, ”Initial Sash Position”, self.<strong>in</strong>itpos,<br />
-1000, 1000, self)<br />
if <strong>in</strong>itpos != -1:<br />
self.<strong>in</strong>itpos = <strong>in</strong>itpos<br />
248 / 565
def OnExit(self, evt):<br />
self.Close()<br />
app = wx.PySimpleApp(redirect=True)<br />
frm = SplitterExampleFrame(None, ”Splitter Example”)<br />
frm.SetSize((600,500))<br />
frm.Show()<br />
app.SetTopW<strong>in</strong>dow(frm)<br />
app.Ma<strong>in</strong>Loop()<br />
<br />
FalseTrue<br />
IsSplit()8.12<br />
Unsplit(toRemove=None)toRemove<br />
wx.W<strong>in</strong>dow<br />
toRemoveNone<br />
<strong>wxPython</strong><br />
unsplitTrue<br />
toRemoveFalse<br />
GetW<strong>in</strong>dow1()<br />
GetW<strong>in</strong>dow2()GetW<strong>in</strong>dow1()<br />
GetW<strong>in</strong>dow2()<br />
ReplaceW<strong>in</strong>dow(w<strong>in</strong>Old, w<strong>in</strong>New)w<strong>in</strong>Old<br />
wx.W<strong>in</strong>doww<strong>in</strong>New<br />
8.4.3 <br />
<br />
8.9<br />
<br />
<br />
<br />
249 / 565
8.9 <br />
wx.SP_3D<br />
wx.SP_3DBORDER<br />
wx.SP_3DSASH<br />
wx.SP_BORDER<br />
wx.SP_LIVE_Update<br />
<br />
<br />
<br />
wx.SP_NOBORDER<br />
wx.SP_NO_XP_THEME W<strong>in</strong>dows XPXP<br />
<br />
wx.SP_PERMIT_UNSPLIT<br />
0<br />
8.4.4 <br />
<br />
SetSashPosition(position,redraw=True)<br />
position<br />
redrawTrue<br />
<br />
GetSashPosition()<br />
<br />
<br />
0<br />
SetM<strong>in</strong>imumPaneSize(paneSize)<br />
paneSize<br />
<br />
wx.SP_PERMIT_UNSPLIT<br />
GetM<strong>in</strong>imumPaneSize()<br />
250 / 565
SetSplitMode(mode)mode<br />
wx.SPLIT_VERTICALwx.SPLIT_HORIZONTAL<br />
<br />
GetSplitMode()<br />
<br />
GetSplitMode()<br />
wx.SP_LIVE_Update<br />
<br />
UpdateSize()<br />
8.4.5 <br />
wx.SplitterEvent<br />
8.10<br />
8.10 <br />
EVT_SPLITTER_DCLICK<br />
Veto()<br />
EVT_SPLITTER_SASH_POS_CHANGED<br />
Veto()<br />
<br />
EVT_SPLITTER_SASH_POS_CHANGING<br />
Veto()<br />
<br />
EVT_SPLITTER_UNSPLIT<br />
wx.CommandEvent<br />
<br />
GetSashPosition()<br />
SetSashPosition(pos)<br />
SetSashPosition(pos)<br />
GetX() GetY()<br />
GetW<strong>in</strong>dowBe<strong>in</strong>gRemoved()<br />
<br />
251 / 565
8.5 <br />
1<strong>wxPython</strong>wx.Framewx.Dialog<br />
wx.Framewx.Frame<strong>wxPython</strong><br />
wx.Frame<br />
wx.Panel<br />
<br />
2wx.Frame<br />
<br />
<br />
“”<br />
3Close()<br />
Destroy()<br />
<br />
4<strong>wxPython</strong> ID<br />
<br />
5wx.ScrolledW<strong>in</strong>dow<br />
sizer<br />
<strong>wxPython</strong>virtual size<br />
<br />
6<br />
wx.MDIParentFrameMDIwx.M<strong>in</strong>iFrame<br />
SetShape()<br />
<br />
<br />
<br />
7wx.SplitterW<strong>in</strong>dow<br />
<br />
<br />
<br />
252 / 565
9<br />
9.1 <br />
<br />
<strong>wxPython</strong><br />
<br />
<br />
<br />
9.1.1 <br />
<br />
9.1<br />
<strong>wxPython</strong><br />
<br />
9.1 <br />
9.19.1<br />
<br />
stdout()<br />
9.1 <br />
import wx<br />
class SubclassDialog(wx.Dialog):<br />
def __<strong>in</strong>it__(self):#<br />
wx.Dialog.__<strong>in</strong>it__(self, None, -1, ’Dialog Subclass’,<br />
size=(300, 100))<br />
okButton = wx.Button(self, wx.ID_OK, ”OK”, pos=(15, 15))<br />
okButton.SetDefault()<br />
253 / 565
cancelButton = wx.Button(self, wx.ID_CANCEL, ”Cancel”,<br />
pos=(115, 15))<br />
if __name__ == ’__ma<strong>in</strong>__’:<br />
app = wx.PySimpleApp()<br />
app.Ma<strong>in</strong>Loop()<br />
dialog = SubclassDialog()<br />
result = dialog.ShowModal()#<br />
if result == wx.ID_OK:<br />
pr<strong>in</strong>t ”OK”<br />
else:<br />
pr<strong>in</strong>t ”Cancel”<br />
dialog.Destroy()<br />
wx.Frame__<strong>in</strong>it__<br />
wx.Dialogwx.Panel<br />
<br />
wx.Paneltab<br />
wx.Dialog<br />
ShowModal()Show()<br />
ShowModal()<br />
<br />
EndModal(retCode)<br />
retCodeShowModal()<br />
<br />
<br />
<br />
<br />
<br />
9.1<br />
wxDialog<strong>wxPython</strong> ID<br />
wx.ID_OK IDwx.Button<br />
wx.ID_OKShowModal()<br />
wx.ID_CANCEL ID<br />
ShowModal()wx.ID_CANCEL<br />
254 / 565
9.1<br />
if<br />
wx.ID_OK<br />
<br />
C+<br />
+Python<br />
<br />
<br />
ShowModal()<br />
Ma<strong>in</strong>Loop()<br />
<br />
9.1.2 <br />
<br />
wx.MessageDialogwx.TextEntryDialog<br />
wx.S<strong>in</strong>gleChoiceDialog<br />
<br />
<br />
yes/no<br />
9.2<br />
9.2<br />
9.2<br />
255 / 565
9.2 <br />
import wx<br />
if __name__ == ”__ma<strong>in</strong>__”:<br />
app = wx.PySimpleApp()<br />
# <br />
dlg = wx.MessageDialog(None, ”Is this explanation OK”,<br />
’A Message Box’,<br />
wx.YES_NO | wx.ICON_QUESTION)<br />
retCode = dlg.ShowModal()<br />
if (retCode == wx.ID_YES):<br />
pr<strong>in</strong>t ”yes”<br />
else:<br />
pr<strong>in</strong>t ”no”<br />
dlg.Destroy()<br />
#1 <br />
retCode = wx.MessageBox(“Is this way easier”, ”Via Function”,<br />
wx.YES_NO | wx.ICON_QUESTION)<br />
9.2<br />
wx.MessageDialogShowModal()<br />
<br />
wx.MessageDialog<br />
<br />
wx.MessageDialog(parent, message, caption=”Message box”,<br />
style=wx.OK | wx.CANCEL, pos=wx.DefaultPosition)<br />
message\n<br />
captionpos<br />
——W<strong>in</strong>dows<br />
wx.MessageDialog<br />
9.1<br />
256 / 565
9.1 wx.MessageDialog<br />
wx.CANCELcancelID<br />
wx.ID_CANCEL<br />
wx.NO_DEFAULTwx.YES_NONo<br />
wx.OKOKIDwx.ID_OK<br />
wx.YES_DEFAULTwx.YES_NOYes<br />
<br />
wx.YES_NOYesNoIDwx.ID_YESwx.ID_NO<br />
9.2<br />
9.2 wx.MessageDialog<br />
wx.ICON_ERROR<br />
wx.ICON_EXCLAMATION<br />
wx.ICON_HANDwx.ICON_ERROR<br />
wx.ICON_INFORMATIONi<br />
wx.ICON_QUESTION<br />
wx.STAY_ON_TOP<br />
<strong>wxPython</strong><br />
9.2ShowModal()<br />
<br />
wx.ID_OK, wx.ID_CANCELwx.ID_YES, wx.ID_NO<br />
<br />
<br />
9.2#1<br />
wx.MessageBox()ShowModal()<br />
wx.YES, wx.NO, wx.CANCEL, wx.OKMessageDialog<br />
<br />
257 / 565
wx.MessageBox(message, caption=”Message”, style=wx.OK)<br />
message, caption, style<br />
<strong>wxPython</strong><br />
<br />
<br />
<br />
<br />
<br />
<strong>wxPython</strong>wx.lib.dialogs.ScrolledMessageDialog<br />
<br />
wx.lib.dialogs.ScrolledMessageDialog(parent, msg, caption,<br />
pos=wx.wxDefaultPosition, size=(500,300))<br />
<strong>wxPython</strong><br />
OK<br />
9.1.3 <br />
wx.TextEntryDialog<br />
<br />
9.3<br />
9.3 <br />
9.39.3<br />
258 / 565
9.3<br />
import wx<br />
if __name__ == ”__ma<strong>in</strong>__”:<br />
app = wx.PySimpleApp()<br />
dialog = wx.TextEntryDialog(None,<br />
”What k<strong>in</strong>d of text would you like to enter”,<br />
”Text Entry”, ”Default Value”, style=wx.OK|wx.CANCEL)<br />
if dialog.ShowModal() == wx.ID_OK:<br />
pr<strong>in</strong>t ”You entered: %s” % dialog.GetValue()<br />
dialog.Destroy()<br />
<br />
wx.TextEntryDialog<br />
wx.TextEntryDialog(parent, message, caption=”Please enter text”,<br />
defaultValue=””, style=wx.OK | wx.CANCEL | wx.CENTRE,<br />
pos=wx.DefaultPosition)<br />
messagecaption<br />
defaultValuestylewx.OK<br />
wx.CANCEL<br />
wx.TextCtrl<br />
wx.TE_PASSWORD<br />
wx.TE_MULTILINE<br />
wx.TE_LEFT, wx.TE_CENTRE, wx.TE_RIGHT<br />
<br />
9.3<br />
<br />
GetValue()Cancel<br />
<br />
SetValue()<br />
259 / 565
1wx.GetTextFromUser()<br />
2wx.GetPasswordFromUser()<br />
3wx.GetNumberFromUser()<br />
9.3wx.GetTextFromUser()<br />
wx.GetTextFromUser(message, caption=”Input text”,<br />
default_value=””, parent=None)<br />
message, caption, default_value, parentwx.TextEntryDialog<br />
OK<br />
Cancel<br />
wx.GetPasswordFromUser()<br />
wx.GetPasswordFromUser(message, caption=”Input text”,<br />
default_value=””, parent=None)<br />
<br />
OKCancel<br />
<br />
wx.GetNumberFromUser()<br />
wx.GetNumberFromUser(message, prompt, caption, value, m<strong>in</strong>=0,<br />
max=100, parent=None)<br />
messageprompt<br />
valuem<strong>in</strong>max<br />
OK<br />
<br />
-1<br />
<br />
260 / 565
9.1.4 <br />
<br />
wx.S<strong>in</strong>gleChoiceDialog9.4<br />
<br />
9.4 <br />
9.49.4<br />
9.4 <br />
import wx<br />
if __name__ == ”__ma<strong>in</strong>__”:<br />
app = wx.PySimpleApp()<br />
choices = [“Alpha”, ”Baker”, ”Charlie”, ”Delta”]<br />
dialog = wx.S<strong>in</strong>gleChoiceDialog(None, ”Pick A Word”, ”Choices”,<br />
choices)<br />
if dialog.ShowModal() == wx.ID_OK:<br />
pr<strong>in</strong>t ”You selected: %s\n” % dialog.GetStr<strong>in</strong>gSelection()<br />
dialog.Destroy()<br />
wx.S<strong>in</strong>gleChoiceDialog<br />
wx.S<strong>in</strong>gleChoiceDialog(parent, message, caption, choices,<br />
clientData=None, style=wx.OK | wx.CANCEL | wx.CENTRE,<br />
pos=wx.DefaultPosition)<br />
261 / 565
messagecaption<br />
choices<br />
styleOKCancle<br />
centreposW<strong>in</strong>dows<br />
<br />
SetSelection(selection)selection<br />
GetSelection()——<br />
GetStr<strong>in</strong>gSelection()——<br />
<br />
wx.GetS<strong>in</strong>gleChoice<br />
<br />
wx.GetS<strong>in</strong>gleChoice(message, caption, aChoices, parent=None)<br />
message, caption, parentwx.S<strong>in</strong>gleChoiceDialog<br />
aChoicesOK<br />
Cancel<br />
<br />
wx.GetS<strong>in</strong>gleChoiceIndex:<br />
wx.GetS<strong>in</strong>gleChoiceIndex(message, caption, aChoices, parent=None)<br />
OK<br />
Cancel-1<br />
9.1.5 <br />
<br />
<br />
<strong>wxPython</strong>9.5<br />
262 / 565
9.5<br />
9.59.5<br />
9.5 <br />
import wx<br />
if __name__ == ”__ma<strong>in</strong>__”:<br />
app = wx.PySimpleApp()<br />
progressMax = 100<br />
dialog = wx.ProgressDialog(“A progress box”, ”Time rema<strong>in</strong><strong>in</strong>g”, progressMax,<br />
style=wx.PD_CAN_ABORT | wx.PD_ELAPSED_TIME | wx.PD_REMAIN<br />
ING_TIME)<br />
keepGo<strong>in</strong>g = True<br />
count = 0<br />
while keepGo<strong>in</strong>g and count < progressMax:<br />
count = count + 1<br />
wx.Sleep(1)<br />
keepGo<strong>in</strong>g = dialog.Update(count)<br />
dialog.Destroy()<br />
<br />
wx.ProgressDialog(title, message, maximum=100, parent=None,<br />
style=wx.PD_AUTO_HIDE | wx.PD_APP_MODAL)<br />
titlemessage<br />
maximum<br />
263 / 565
9.3 wx.ProgressDialog<br />
9.3 wx.ProgressDialog<br />
wx.PD_APP_MODAL<br />
<br />
<br />
wx.PD_AUTO_HIDE<br />
wx.PD_CAN_ABORTCancel<br />
<br />
wx.PD_ELAPSED_TIME<br />
wx.PD_ESTIMATED_TIME<br />
<br />
wx.PD_REMAINING_TIME(-<br />
)<br />
Update(value,newmsg=””)value<br />
update<br />
newmsg<br />
<br />
Update()TrueCancel<br />
Update()False<br />
Update()<br />
9.2 <br />
<br />
<strong>wxPython</strong><br />
<strong>wxPython</strong><br />
<br />
9.2.1 <br />
<strong>wxPython</strong>wx.FileDialog<br />
W<strong>in</strong>dows9.6<br />
264 / 565
9.6<br />
<br />
9.6<br />
9.6 wx.FileDialog<br />
import wx<br />
import os<br />
if __name__ == ”__ma<strong>in</strong>__”:<br />
app = wx.PySimpleApp()<br />
wildcard = ”Python source (*.py)|*.py|” \<br />
”Compiled Python (*.pyc)|*.pyc|” \<br />
”All files (*.*)|*.*”<br />
dialog = wx.FileDialog(None, ”Choose a file”, os.getcwd(),<br />
””, wildcard, wx.OPEN)<br />
if dialog.ShowModal() == wx.ID_OK:<br />
pr<strong>in</strong>t dialog.GetPath()<br />
dialog.Destroy()<br />
265 / 565
wx.FileDialog(parent, message=”Choose a file”, defaultDir=””,<br />
defaultFile=””, wildcard=”*.*”, style=0,<br />
pos=wx.DefaultPosition)<br />
messagedefaultDir<br />
<br />
defaultFilewildcard<br />
*<br />
*.py|||——9.6<br />
<br />
“Python source (*.py)|*.py|Compiled Python (*.pyc)|*.pyc|<br />
All files (*.*)|*.*”<br />
9.6<br />
pos<br />
<br />
wx.FileDialogwx.OPENwx.SAVE<br />
<br />
<br />
wx.HIDE_READONLY<br />
wx.MULTIPLE<br />
wx.OVERWRITE_PROMPT<br />
<br />
wx.CHANGE_DIR<br />
<br />
<br />
<br />
directoryfilename, style, message, wildcard<br />
Get/Set<br />
266 / 565
wx.OK<br />
GetPath()<br />
wx.MULTIPLEGetPaths()<br />
GetPath()Python<br />
GetFilterIndex()<br />
SetFilterIndex()<br />
<br />
wx.FileSelector(message, default_path=””, default_filename=””,<br />
default_extension=””, wildcard=”*.*’’, flags=0, parent=None,<br />
x=-1, y=-1)<br />
message, default_path, default_filename, wildcard<br />
flagsstyledefault_extension<br />
<br />
OKCancel<br />
<br />
<br />
wx.DirDialog<br />
9.7<br />
9.7<br />
9.7 <br />
import wx<br />
if __name__ == ”__ma<strong>in</strong>__”:<br />
app = wx.PySimpleApp()<br />
dialog = wx.DirDialog(None, ”Choose a directory:”,<br />
style=wx.DD_DEFAULT_STYLE | wx.DD_NEW_DIR_BUTTON)<br />
if dialog.ShowModal() == wx.ID_OK:<br />
pr<strong>in</strong>t dialog.GetPath()<br />
dialog.Destroy()<br />
267 / 565
9.7<br />
<br />
wx.DirDialog(parent, message=”Choose a directory”, defaultPath=””,<br />
style=0, pos = wx.DefaultPosition, size = wx.DefaultSize,<br />
name=”wxDirCtrl”)<br />
message<br />
defaultPath<br />
possizeW<strong>in</strong>dowsname<br />
wx.DD_NEW_DIR_BUTTON<br />
W<strong>in</strong>dows<br />
<br />
wx.DirDialogpath, message, styleget*set*<br />
GetPath()<br />
<br />
wx.DirSelector(message=wx.DirSelectorPromptStr, default_path=””,<br />
style=0, pos=wxDefaultPosition, parent=None)<br />
OK<br />
Cancel<br />
268 / 565
9.2.2 <br />
<strong>wxPython</strong><br />
9.8W<strong>in</strong>dows<br />
<br />
9.8 9.8<br />
<br />
9.8 <br />
import wx<br />
if __name__ == ”__ma<strong>in</strong>__”:<br />
app = wx.PySimpleApp()<br />
dialog = wx.FontDialog(None, wx.FontData())<br />
if dialog.ShowModal() == wx.ID_OK:<br />
data = dialog.GetFontData()<br />
font = data.GetChosenFont()<br />
colour = data.GetColour()<br />
pr<strong>in</strong>t ’You selected: ”%s”, %d po<strong>in</strong>ts\n’ % (<br />
font.GetFaceName(), font.GetPo<strong>in</strong>tSize())<br />
dialog.Destroy()<br />
9.8<br />
269 / 565
wx.FontDialog <br />
wx.FontDialog(parent, data)<br />
<br />
datawx.FontDatawx.FontData<br />
GetFontData()<br />
wx.FontData<br />
9.8wx.FontDataget*<br />
wx.FontData——<br />
9.4<br />
9.4 wx.FontData<br />
GetAllowSymbols()<br />
SetAllowSymbols(allowSymbols)<br />
d<strong>in</strong>gbatsW<strong>in</strong>dowsTrue<br />
GetChosenFont()<br />
SetChosenFont(font)wx.Font<br />
Nonewx.Font12<br />
GetColour()<br />
SetColour(colour)set*<br />
get*wx.Colourset*colour<br />
wx.Colourblack<br />
GetEnableEffects()<br />
EnableEffects(enable)W<strong>in</strong>dows<br />
<br />
GetInitialFont()<br />
SetInitialFont(font)<br />
None<br />
SetRange(m<strong>in</strong>, max)W<strong>in</strong>dows<br />
0~0<br />
GetShowHelp()<br />
SetShowHelp()TrueW<strong>in</strong>dows<br />
False<br />
270 / 565
wx.FontData<br />
wx.GetFontFromUser(parent, fontInit)<br />
fontInitwx.Font<br />
wx.FontOKwx.Font.Ok()<br />
TrueFalse<br />
9.2.3 <br />
<br />
9.9<br />
9.9<br />
9.9<br />
import wx<br />
if __name__ == ”__ma<strong>in</strong>__”:<br />
app = wx.PySimpleApp()<br />
dialog = wx.ColourDialog(None)<br />
dialog.GetColourData().SetChooseFull(True)<br />
if dialog.ShowModal() == wx.ID_OK:<br />
data = dialog.GetColourData()<br />
pr<strong>in</strong>t ’You selected: %s\n’ % str(data.GetColour().Get())<br />
dialog.Destroy()<br />
271 / 565
9.9<br />
<strong>wxPython</strong>wx.ColourDialog<br />
<br />
wx.ColourDialog(parent, data=None)<br />
datawx.ColourData<br />
<br />
1GetChooseFulłSetChooseFull(flag)W<strong>in</strong>dows<br />
<br />
<br />
2GetColour/SetColour(colour)get*<br />
black<br />
<br />
3GetCustomColour(i)/SetCustomColour(i, colour)<br />
ii[0,15]<br />
<br />
wx.ColorData<br />
wx.GetColourFromUser(parent, colInit)<br />
272 / 565
colInitwx.Colour<br />
wx.ColourOK<br />
wx.Colour.OK()TrueCancel<br />
wx.Colour.OK()False<br />
9.2.4 <br />
<br />
<strong>wxPython</strong><br />
wx.lib.imagebrowser.ImageDialog9.10<br />
9.10<br />
9.10 <br />
import wx<br />
import wx.lib.imagebrowser as imagebrowser<br />
if __name__ == ”__ma<strong>in</strong>__”:<br />
app = wx.PySimpleApp()<br />
dialog = imagebrowser.ImageDialog(None)<br />
if dialog.ShowModal() == wx.ID_OK:<br />
pr<strong>in</strong>t ”You Selected File: ” + dialog.GetFile()<br />
dialog.Destroy()<br />
9.10<br />
273 / 565
wx.lib.imagebrowser.ImageDialog<br />
<br />
Python<br />
ImageDialog(parent, set_dir=None)<br />
set_dir<br />
GetFile()<br />
GetDirectory()<br />
9.3 <br />
<br />
9.11<br />
<br />
9.11<br />
<strong>wxPython</strong>wx.wizard.Wizard<br />
<br />
wx.wizard.WizardPageSimplewx.wizard.WizardPage<br />
wx.Panel<br />
Nextwx.wizard.WizardPage<br />
274 / 565
wx.wizard.WizardPageSimple<br />
9.119.11<br />
9.11 <br />
import wx<br />
import wx.wizard<br />
class TitledPage(wx.wizard.WizardPageSimple):#1 <br />
def __<strong>in</strong>it__(self, parent, title):<br />
wx.wizard.WizardPageSimple.__<strong>in</strong>it__(self, parent)<br />
self.sizer = wx.BoxSizer(wx.VERTICAL)<br />
self.SetSizer(self.sizer)<br />
titleText = wx.StaticText(self, -1, title)<br />
titleText.SetFont(<br />
wx.Font(18, wx.SWISS, wx.NORMAL, wx.BOLD))<br />
self.sizer.Add(titleText, 0,<br />
wx.ALIGN_CENTRE | wx.ALL, 5)<br />
self.sizer.Add(wx.StaticL<strong>in</strong>e(self, -1), 0,<br />
wx.EXPAND | wx.ALL, 5)<br />
if __name__ == ”__ma<strong>in</strong>__”:<br />
app = wx.PySimpleApp()<br />
wizard = wx.wizard.Wizard(None, -1, ”Simple Wizard”)# <br />
# <br />
page1 = TitledPage(wizard, ”Page 1”)<br />
page2 = TitledPage(wizard, ”Page 2”)<br />
page3 = TitledPage(wizard, ”Page 3”)<br />
page4 = TitledPage(wizard, ”Page 4”)<br />
page1.sizer.Add(wx.StaticText(page1, -1,<br />
”Test<strong>in</strong>g the wizard”))<br />
page4.sizer.Add(wx.StaticText(page4, -1,<br />
”This is the last page.”))<br />
#2 <br />
wx.wizard.WizardPageSimple_Cha<strong>in</strong>(page1, page2)<br />
wx.wizard.WizardPageSimple_Cha<strong>in</strong>(page2, page3)<br />
wx.wizard.WizardPageSimple_Cha<strong>in</strong>(page3, page4)<br />
275 / 565
wizard.FitToPage(page1)#3 <br />
if wizard.RunWizard(page1):#4 <br />
pr<strong>in</strong>t ”Success”<br />
wizard.Destroy()<br />
#1 <br />
<br />
<br />
#2 wx.wizard.WizardPageSimple_Cha<strong>in</strong>()<br />
SetNext()SetPrev()<br />
#3 FitToSize()<br />
<br />
#4 <br />
F<strong>in</strong>ish<br />
RunWizard()True<br />
wx.wizard.Wizard<br />
wx.wizard.Wizard(parent, id=-1, title=wx.EmptyStr<strong>in</strong>g,<br />
bitmap=wx.NullBitmap, pos=wx.DefaultPosition)<br />
parent, id, title, poswx.Panelbitmap<br />
<br />
wx.wizard.WIZARD_EX_HELPBUTTON<br />
8<br />
9.11#3FitToSize()<br />
wx.SizeSetPageSize()<br />
GetPageSize()<br />
<br />
GetCurrentPage()<br />
NoneHasNextPage()<br />
HasPrevPage()<br />
276 / 565
RunWizard()9.11#4<br />
9.5<br />
wx.wizard.WizardEvent<br />
GetPage()wx.WizardPage<br />
GetDirection()<br />
TrueGetDirection()False<br />
9.5 wx.wizard.WizardDialog<br />
EVT_WIZARD_CANCELCancelVeto()<br />
<br />
EVT_WIZARD_FINISHED F<strong>in</strong>ish<br />
EVT_WIZARD_HELPHelp<br />
EVT_WIZARD_PAGE_CHANGED<br />
EVT_WIZARD_PAGE_CHANGING<br />
<br />
<br />
wx.wizard.WizardPageSimple<br />
<br />
wx.wizard.WizardPageSimple(parent=None, prev=None, next=None)<br />
SetPrev()SetNext()<br />
wx.wizard.WizardPageSimple_Cha<strong>in</strong>()<br />
<br />
wx.wizard.WizardPage<br />
<br />
<br />
wx.WizardPage(parent, bitmap=wx.NullBitmap, resource=None)<br />
bitmap<br />
resource<strong>wxPython</strong><br />
277 / 565
GetPrev()GetNext()<br />
<br />
9.4 <br />
<br />
<strong>wxPython</strong>9.12<br />
<br />
9.12<br />
9.12<br />
9.12<br />
import wx<br />
if __name__ == ”__ma<strong>in</strong>__”:<br />
app = wx.PySimpleApp()<br />
provider = wx.CreateFileTipProvider(“tips.txt”, 0)<br />
wx.ShowTip(None, provider, True)<br />
<br />
wx.TipProvider<br />
wx.CreateFileTipProvider(filename, currentTip)<br />
278 / 565
filenamecurrentTip<br />
0<br />
<br />
#<br />
<br />
You can do startup tips very easily.<br />
Feel the force, Luke.<br />
providerwx.PyTipProvider<br />
wx.TipProviderGetTip()<br />
<br />
wx.ShowTip():<br />
wx.ShowTip(parent, tipProvider, showAtStartup)<br />
parenttipProvider<br />
wx.CreateFileTipProvidershowAtStartup<br />
<br />
<br />
9.5 validator<br />
<strong>wxPython</strong><br />
<br />
<strong>wxPython</strong><br />
<br />
<br />
1<br />
2<br />
3<br />
9.5.1 <br />
wx.Validator<br />
C++ wxWidget<strong>wxPython</strong><br />
279 / 565
PythonPython<br />
wx.PyValidator<br />
Clone()<br />
<br />
<br />
<br />
<br />
SetValidator(validator)<br />
Validate(parent)<br />
parent<br />
<br />
self.GetW<strong>in</strong>dow()<br />
Validate(parent)True<br />
FalseValidate()<br />
x.MessageBox()<strong>wxPython</strong><br />
<br />
Validate()OK<br />
wx.ID_OK IDOK<br />
<strong>wxPython</strong>Validate()<br />
False9.13<br />
<br />
9.13 <br />
import wx<br />
about_txt = ”””\<br />
The validator used <strong>in</strong> this example will ensure that the text<br />
controls are not empty when you press the Ok button, and<br />
will not let you leave if any of the Validations fail.”””<br />
class NotEmptyValidator(wx.PyValidator):# <br />
def __<strong>in</strong>it__(self):<br />
wx.PyValidator.__<strong>in</strong>it__(self)<br />
def Clone(self):<br />
280 / 565
”””<br />
Note that every validator must implement the Clone() method.<br />
”””<br />
return NotEmptyValidator()<br />
def Validate(self, w<strong>in</strong>):#1 <br />
textCtrl = self.GetW<strong>in</strong>dow()<br />
text = textCtrl.GetValue()<br />
if len(text) == 0:<br />
wx.MessageBox(“This field must conta<strong>in</strong> some text!”, ”Error”)<br />
textCtrl.SetBackgroundColour(“p<strong>in</strong>k”)<br />
textCtrl.SetFocus()<br />
textCtrl.Refresh()<br />
return False<br />
else:<br />
textCtrl.SetBackgroundColour(<br />
wx.SystemSett<strong>in</strong>gs_GetColour(wx.SYS_COLOUR_WINDOW))<br />
textCtrl.Refresh()<br />
return True<br />
def TransferToW<strong>in</strong>dow(self):<br />
return True<br />
def TransferFromW<strong>in</strong>dow(self):<br />
return True<br />
class MyDialog(wx.Dialog):<br />
def __<strong>in</strong>it__(self):<br />
wx.Dialog.__<strong>in</strong>it__(self, None, -1, ”Validators: validat<strong>in</strong>g”)<br />
# Create the text controls<br />
about = wx.StaticText(self, -1, about_txt)<br />
name_l = wx.StaticText(self, -1, ”Name:”)<br />
email_l = wx.StaticText(self, -1, ”Email:”)<br />
phone_l = wx.StaticText(self, -1, ”Phone:”)<br />
#2 <br />
281 / 565
name_t = wx.TextCtrl(self, validator=NotEmptyValidator())<br />
email_t = wx.TextCtrl(self, validator=NotEmptyValidator())<br />
phone_t = wx.TextCtrl(self, validator=NotEmptyValidator())<br />
# Use standard button IDs<br />
okay = wx.Button(self, wx.ID_OK)<br />
okay.SetDefault()<br />
cancel = wx.Button(self, wx.ID_CANCEL)<br />
# Layout with sizers<br />
sizer = wx.BoxSizer(wx.VERTICAL)<br />
sizer.Add(about, 0, wx.ALL, 5)<br />
sizer.Add(wx.StaticL<strong>in</strong>e(self), 0, wx.EXPAND|wx.ALL, 5)<br />
fgs = wx.FlexGridSizer(3, 2, 5, 5)<br />
fgs.Add(name_l, 0, wx.ALIGN_RIGHT)<br />
fgs.Add(name_t, 0, wx.EXPAND)<br />
fgs.Add(email_l, 0, wx.ALIGN_RIGHT)<br />
fgs.Add(email_t, 0, wx.EXPAND)<br />
fgs.Add(phone_l, 0, wx.ALIGN_RIGHT)<br />
fgs.Add(phone_t, 0, wx.EXPAND)<br />
fgs.AddGrowableCol(1)<br />
sizer.Add(fgs, 0, wx.EXPAND|wx.ALL, 5)<br />
btns = wx.StdDialogButtonSizer()<br />
btns.AddButton(okay)<br />
btns.AddButton(cancel)<br />
btns.Realize()<br />
sizer.Add(btns, 0, wx.EXPAND|wx.ALL, 5)<br />
self.SetSizer(sizer)<br />
sizer.Fit(self)<br />
app = wx.PySimpleApp()<br />
dlg = MyDialog()<br />
dlg.ShowModal()<br />
dlg.Destroy()<br />
282 / 565
app.Ma<strong>in</strong>Loop()<br />
#1 <br />
<br />
9.13<br />
#2 <br />
9.13<br />
<br />
<strong>wxPython</strong><br />
<br />
Validate()<br />
wx.WS_EX_VALIDATE_RECURSIVELY<br />
Validate()ValidateFalse<br />
<br />
9.5.2 <br />
<br />
<br />
9.14<br />
283 / 565
9.14<br />
<br />
TransferToW<strong>in</strong>dow()<br />
TransferFromW<strong>in</strong>dow()OK<br />
<br />
<br />
<br />
9.14<br />
<br />
TransferToW<strong>in</strong>dow()<br />
TransferFromW<strong>in</strong>dow()<br />
<br />
9.14 <br />
import wx<br />
import ppr<strong>in</strong>t<br />
about_txt = ”””\<br />
The validator used <strong>in</strong> this example shows how the validator<br />
can be used to transfer data to and from each text control<br />
automatically when the dialog is shown and dismissed.”””<br />
class DataXferValidator(wx.PyValidator):# <br />
284 / 565
def __<strong>in</strong>it__(self, data, key):<br />
wx.PyValidator.__<strong>in</strong>it__(self)<br />
self.data = data<br />
self.key = key<br />
def Clone(self):<br />
”””<br />
Note that every validator must implement the Clone() method.<br />
”””<br />
return DataXferValidator(self.data, self.key)<br />
def Validate(self, w<strong>in</strong>):# <br />
return True<br />
def TransferToW<strong>in</strong>dow(self):# <br />
textCtrl = self.GetW<strong>in</strong>dow()<br />
textCtrl.SetValue(self.data.get(self.key, ””))<br />
return True<br />
def TransferFromW<strong>in</strong>dow(self):# <br />
textCtrl = self.GetW<strong>in</strong>dow()<br />
self.data[self.key] = textCtrl.GetValue()<br />
return True<br />
class MyDialog(wx.Dialog):<br />
def __<strong>in</strong>it__(self, data):<br />
wx.Dialog.__<strong>in</strong>it__(self, None, -1, ”Validators: data transfer”)<br />
# Create the text controls<br />
about = wx.StaticText(self, -1, about_txt)<br />
name_l = wx.StaticText(self, -1, ”Name:”)<br />
email_l = wx.StaticText(self, -1, ”Email:”)<br />
phone_l = wx.StaticText(self, -1, ”Phone:”)<br />
# <br />
name_t = wx.TextCtrl(self, validator=DataXferValidator(data, ”name”))<br />
email_t = wx.TextCtrl(self, validator=DataXferValidator(data, ”email”))<br />
phone_t = wx.TextCtrl(self, validator=DataXferValidator(data, ”phone”))<br />
285 / 565
# Use standard button IDs<br />
okay = wx.Button(self, wx.ID_OK)<br />
okay.SetDefault()<br />
cancel = wx.Button(self, wx.ID_CANCEL)<br />
# Layout with sizers<br />
sizer = wx.BoxSizer(wx.VERTICAL)<br />
sizer.Add(about, 0, wx.ALL, 5)<br />
sizer.Add(wx.StaticL<strong>in</strong>e(self), 0, wx.EXPAND|wx.ALL, 5)<br />
fgs = wx.FlexGridSizer(3, 2, 5, 5)<br />
fgs.Add(name_l, 0, wx.ALIGN_RIGHT)<br />
fgs.Add(name_t, 0, wx.EXPAND)<br />
fgs.Add(email_l, 0, wx.ALIGN_RIGHT)<br />
fgs.Add(email_t, 0, wx.EXPAND)<br />
fgs.Add(phone_l, 0, wx.ALIGN_RIGHT)<br />
fgs.Add(phone_t, 0, wx.EXPAND)<br />
fgs.AddGrowableCol(1)<br />
sizer.Add(fgs, 0, wx.EXPAND|wx.ALL, 5)<br />
btns = wx.StdDialogButtonSizer()<br />
btns.AddButton(okay)<br />
btns.AddButton(cancel)<br />
btns.Realize()<br />
sizer.Add(btns, 0, wx.EXPAND|wx.ALL, 5)<br />
self.SetSizer(sizer)<br />
sizer.Fit(self)<br />
app = wx.PySimpleApp()<br />
data = { ”name” : ”Jordyn Dunn” }<br />
dlg = MyDialog(data)<br />
dlg.ShowModal()<br />
dlg.Destroy()<br />
wx.MessageBox(“You entered these values:\n\n” +<br />
ppr<strong>in</strong>t.pformat(data))<br />
286 / 565
app.Ma<strong>in</strong>Loop()<br />
<br />
TransDataFromW<strong>in</strong>dow()<br />
TransferDataToW<strong>in</strong>dow()<br />
wx.WS_EX_VALIDATE_RECURSIVELY<br />
<br />
9.5.3 <br />
<br />
<br />
9.12<br />
9.15<br />
<br />
<br />
self.B<strong>in</strong>d(wx.EVT_CHAR, self.OnChar)<br />
9.15<br />
9.15 <br />
import wx<br />
import str<strong>in</strong>g<br />
287 / 565
about_txt = ”””\<br />
The validator used <strong>in</strong> this example will validate the <strong>in</strong>put on the fly<br />
<strong>in</strong>stead of wait<strong>in</strong>g until the okay button is pressed. The first field<br />
will not allow digits to be typed, the second will allow anyth<strong>in</strong>g<br />
and the third will not allow alphabetic characters to be entered.<br />
“””<br />
class CharValidator(wx.PyValidator):<br />
def __<strong>in</strong>it__(self, flag):<br />
wx.PyValidator.__<strong>in</strong>it__(self)<br />
self.flag = flag<br />
self.B<strong>in</strong>d(wx.EVT_CHAR, self.OnChar)# <br />
def Clone(self):<br />
”””<br />
Note that every validator must implement the Clone() method.<br />
”””<br />
return CharValidator(self.flag)<br />
def Validate(self, w<strong>in</strong>):<br />
return True<br />
def TransferToW<strong>in</strong>dow(self):<br />
return True<br />
def TransferFromW<strong>in</strong>dow(self):<br />
return True<br />
def OnChar(self, evt):# <br />
key = chr(evt.GetKeyCode())<br />
if self.flag == ”no-alpha” and key <strong>in</strong> str<strong>in</strong>g.letters:<br />
return<br />
if self.flag == ”no-digit” and key <strong>in</strong> str<strong>in</strong>g.digits:<br />
return<br />
evt.Skip()<br />
class MyDialog(wx.Dialog):<br />
def __<strong>in</strong>it__(self):<br />
288 / 565
wx.Dialog.__<strong>in</strong>it__(self, None, -1, ”Validators: behavior modification”)<br />
# Create the text controls<br />
about = wx.StaticText(self, -1, about_txt)<br />
name_l = wx.StaticText(self, -1, ”Name:”)<br />
email_l = wx.StaticText(self, -1, ”Email:”)<br />
phone_l = wx.StaticText(self, -1, ”Phone:”)<br />
# <br />
name_t = wx.TextCtrl(self, validator=CharValidator(“no-digit”))<br />
email_t = wx.TextCtrl(self, validator=CharValidator(“any”))<br />
phone_t = wx.TextCtrl(self, validator=CharValidator(“no-alpha”))<br />
# Use standard button IDs<br />
okay = wx.Button(self, wx.ID_OK)<br />
okay.SetDefault()<br />
cancel = wx.Button(self, wx.ID_CANCEL)<br />
# Layout with sizers<br />
sizer = wx.BoxSizer(wx.VERTICAL)<br />
sizer.Add(about, 0, wx.ALL, 5)<br />
sizer.Add(wx.StaticL<strong>in</strong>e(self), 0, wx.EXPAND|wx.ALL, 5)<br />
fgs = wx.FlexGridSizer(3, 2, 5, 5)<br />
fgs.Add(name_l, 0, wx.ALIGN_RIGHT)<br />
fgs.Add(name_t, 0, wx.EXPAND)<br />
fgs.Add(email_l, 0, wx.ALIGN_RIGHT)<br />
fgs.Add(email_t, 0, wx.EXPAND)<br />
fgs.Add(phone_l, 0, wx.ALIGN_RIGHT)<br />
fgs.Add(phone_t, 0, wx.EXPAND)<br />
fgs.AddGrowableCol(1)<br />
sizer.Add(fgs, 0, wx.EXPAND|wx.ALL, 5)<br />
btns = wx.StdDialogButtonSizer()<br />
btns.AddButton(okay)<br />
btns.AddButton(cancel)<br />
btns.Realize()<br />
sizer.Add(btns, 0, wx.EXPAND|wx.ALL, 5)<br />
self.SetSizer(sizer)<br />
289 / 565
sizer.Fit(self)<br />
app = wx.PySimpleApp()<br />
dlg = MyDialog()<br />
dlg.ShowModal()<br />
dlg.Destroy()<br />
app.Ma<strong>in</strong>Loop()<br />
OnChar()<br />
Skip()<br />
Skip()<br />
Skip()<br />
wx.EVT_CHAR<br />
<br />
<strong>wxPython</strong><br />
<br />
9.6 <br />
1<br />
<strong>wxPython</strong><br />
wx.Dialog<br />
<br />
<br />
2<br />
ShowModal()<br />
OKCancel<br />
<br />
3<strong>wxPython</strong>wx.MessageDialog<br />
wx.TextEntryDialogwx.S<strong>in</strong>gleChoiceDialog<br />
<br />
4wx.ProgressDialog<br />
wx.FileDialog<br />
290 / 565
wx.DirDialog<br />
<br />
5wx.FontDialogwx.ColorDialog<br />
<br />
<br />
6<strong>wxPython</strong><br />
wx.lib.imagebrowser.ImageDialog<br />
<br />
7wx.wizard.Wizard<br />
wx.wizard.WizardSimplePage<br />
wx.wizard.WizardPagewx.wizard.WizardSimplePage<br />
wx.wizard.WizardPage<br />
<br />
8wx.CreateFileTipProviderwx.ShowTip<br />
<br />
9<br />
<br />
<br />
291 / 565
10<strong>wxPython</strong><br />
<br />
<br />
<br />
<br />
FileEditHelp<br />
<br />
<br />
<br />
<strong>wxPython</strong>wx.MenuBar<br />
wx.Menu<br />
wx.MenuBarwx.Menuwx.MenuItem<br />
wx.Menu<br />
5.5<br />
7<br />
<strong>wxPython</strong><br />
10.1 <br />
<br />
·<br />
·<br />
·<br />
·<br />
·<br />
·<br />
·<br />
<br />
<br />
<br />
<br />
292 / 565
5<br />
<br />
10.1.1 <br />
wx.MenuBar<br />
wx.MenuBar()<br />
SetMenuBar()<br />
wx.Frame__<strong>in</strong>it__OnInit()<br />
menubar = wx.MenuBar()<br />
self.SetMenuBar<br />
<br />
<br />
wx.Frame.GetMenuBar()<br />
10.1.2 <br />
<strong>wxPython</strong><br />
wx.Menu<br />
wx.Menu(title=””, style=0)<br />
wx.MenuGTKwx.MENU_TEAROFF<br />
<br />
10.1<br />
10.1<br />
<br />
293 / 565
10.1<br />
10.1 <br />
import wx<br />
class MyFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, -1, ”Simple Menu Example”)<br />
p = wx.Panel(self)<br />
menuBar = wx.MenuBar()# <br />
menu = wx.Menu()# <br />
menuBar.Append(menu, ”Left Menu”)# <br />
menu2 = wx.Menu()<br />
menuBar.Append(menu2, ”Middle Menu”)<br />
menu3 = wx.Menu()<br />
menuBar.Append(menu3, ”Right Menu”)<br />
self.SetMenuBar(menuBar)<br />
if __name__ == ”__ma<strong>in</strong>__”:<br />
app = wx.PySimpleApp()<br />
frame = MyFrame()<br />
frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
<strong>wxPython</strong>API<br />
wx.Menu<br />
<br />
294 / 565
wx.Menuwx.MenuBar<br />
10.1wx.MenuBar<br />
10.1 wx.MenuBar<br />
Append(menu, title)menutitle<br />
TrueFalse<br />
Insert(pos, menu, title)menupos<br />
GetMenu(pos) == menu<br />
0pos0<br />
GetMenuCount()posAppendtitle<br />
True<br />
Remove(pos)pos<br />
<br />
Replace(pos, menu, title)menutitlepos<br />
<br />
wx.MenuBar<br />
10.2<br />
10.2 wx.MenuBar<br />
EnableTop(pos, enable)pos/enable<br />
TrueFalse<br />
GetMenu(pos)<br />
GetMenuCount()<br />
F<strong>in</strong>dMenu(title)title<br />
wx.NOT_FOUND<br />
GetLabelTop(pos)<br />
SetLabelTop(pos, label)<br />
295 / 565
10.1.3 <br />
<br />
wx.MenuAppend()<br />
Append(id, str<strong>in</strong>g, helpStr=””, k<strong>in</strong>d=wx.ITEM_NORMAL)<br />
id<strong>wxPython</strong> IDstr<strong>in</strong>g<br />
helpStr<br />
k<strong>in</strong>d<br />
Append<br />
<br />
10.2 Append()<br />
<br />
10.2 <br />
import wx<br />
class MyFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, -1, ”Simple Menu Example”)<br />
p = wx.Panel(self)<br />
self.CreateStatusBar()<br />
menu = wx.Menu()<br />
simple = menu.Append(-1, ”Simple menu item”, ”This is some help text”)<br />
menu.AppendSeparator()<br />
exit = menu.Append(-1, ”Exit”)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnSimple, simple)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnExit, exit)<br />
menuBar = wx.MenuBar()<br />
menuBar.Append(menu, ”Simple Menu”)<br />
self.SetMenuBar(menuBar)<br />
def OnSimple(self, event):<br />
wx.MessageBox(“You selected the simple menu item”)<br />
def OnExit(self, event):<br />
self.Close()<br />
296 / 565
if __name__ == ”__ma<strong>in</strong>__”:<br />
app = wx.PySimpleApp()<br />
frame = MyFrame()<br />
frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
10.2<br />
10.2 <br />
Append()<br />
<br />
·Prepend(id, str<strong>in</strong>g, helpStr=””, k<strong>in</strong>d=wx.ITEM_NORMAL)<br />
·PrependSeparator()<br />
<strong>in</strong>sert<br />
·Insert(pos, id, str<strong>in</strong>g, helpStr=””, k<strong>in</strong>d=wx.ITEM_NORMAL)<br />
·InsertSeparator(pos)<br />
pos0<br />
<br />
<br />
297 / 565
wx.MenuItem<br />
<br />
wx.MenuItem<br />
<br />
wx.MenuItem(parentMenu=None, id=ID_ANY, text=””,<br />
helpStr<strong>in</strong>g=””, k<strong>in</strong>d=wx.ITEM_NORMAL, subMenu=None)<br />
parentMenuwx.Menu<br />
<br />
<strong>wxPython</strong>id<br />
texthelpStr<strong>in</strong>g<br />
k<strong>in</strong>d<br />
wx.ITEM_NORMAL<br />
subMenunull<br />
<br />
10.3<br />
<br />
wx.Menu<br />
·AppendItem(aMenuItem)<br />
·InsertItem(pos, aMenuItem)<br />
·PrependItem(aMenuItem)<br />
Remove(id)<br />
<strong>wxPython</strong> IDRemoveItem(item)<br />
Remove()<br />
<br />
<br />
wx.Menuget*<br />
GetMenuItemCount()GetMenuItems()<br />
<br />
<br />
10.3<br />
OnAddItem()<br />
<br />
298 / 565
10.3 <br />
import wx<br />
class MyFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, -1,<br />
”Add Menu Items”)<br />
p = wx.Panel(self)<br />
self.txt = wx.TextCtrl(p, -1, ”new item”)<br />
btn = wx.Button(p, -1, ”Add Menu Item”)<br />
self.B<strong>in</strong>d(wx.EVT_BUTTON, self.OnAddItem, btn)# <br />
sizer = wx.BoxSizer(wx.HORIZONTAL)<br />
sizer.Add(self.txt, 0, wx.ALL, 20)<br />
sizer.Add(btn, 0, wx.TOP|wx.RIGHT, 20)<br />
p.SetSizer(sizer)<br />
self.menu = menu = wx.Menu()<br />
simple = menu.Append(-1, ”Simple menu item”)<br />
menu.AppendSeparator()<br />
exit = menu.Append(-1, ”Exit”)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnSimple, simple)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnExit, exit)<br />
menuBar = wx.MenuBar()<br />
menuBar.Append(menu, ”Menu”)<br />
self.SetMenuBar(menuBar)<br />
def OnSimple(self, event):<br />
wx.MessageBox(“You selected the simple menu item”)<br />
def OnExit(self, event):<br />
self.Close()<br />
def OnAddItem(self, event):<br />
item = self.menu.Append(-1, self.txt.GetValue())# <br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnNewItemSelected, item)# <br />
<br />
299 / 565
def OnNewItemSelected(self, event):<br />
wx.MessageBox(“You selected a new item”)<br />
if __name__ == ”__ma<strong>in</strong>__”:<br />
app = wx.PySimpleApp()<br />
frame = MyFrame()<br />
frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
OnAddItem()Append()<br />
<br />
<br />
10.1.4 <br />
8<br />
<br />
wx.CommandEventwx.EVT_MENU<br />
<br />
B<strong>in</strong>d()<br />
wx.EVT_MENUB<strong>in</strong>d()<br />
<br />
<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnExit, exit_menu_item)<br />
selfself.OnExitexit_menu_item<br />
<br />
<br />
<strong>wxPython</strong> ID<br />
wx.EVT_MENUB<strong>in</strong>d()<br />
<br />
<br />
300 / 565
wx.EVT_MENU_RANGE<br />
self.B<strong>in</strong>d(wx.EVT_MENU_RANGE, function, id=menu1, id2=menu2)<br />
[menu1,menu2]<br />
<br />
<br />
<strong>wxPython</strong>wx.MenuEvent10.3<br />
wx.MenuEvent<br />
10.3 wx.MenuEvent<br />
EVT_MENU_CLOSE<br />
EVT_MENU_HIGHLIGHT <br />
ID<br />
EVT_MENU_HIGHLIGHT_ALL<br />
ID——<br />
<br />
EVT_MENU_OPEN<br />
<br />
<br />
10.2 <br />
<br />
<br />
<br />
<br />
10.2.1 <br />
<strong>wxPython</strong><br />
<br />
301 / 565
10.1<br />
F<strong>in</strong>dItemById()<br />
10.4 <br />
import wx<br />
class MyFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, -1,<br />
”F<strong>in</strong>d Item Example”)<br />
p = wx.Panel(self)<br />
self.txt = wx.TextCtrl(p, -1, ”new item”)<br />
btn = wx.Button(p, -1, ”Add Menu Item”)<br />
self.B<strong>in</strong>d(wx.EVT_BUTTON, self.OnAddItem, btn)<br />
sizer = wx.BoxSizer(wx.HORIZONTAL)<br />
sizer.Add(self.txt, 0, wx.ALL, 20)<br />
sizer.Add(btn, 0, wx.TOP|wx.RIGHT, 20)<br />
p.SetSizer(sizer)<br />
self.menu = menu = wx.Menu()<br />
simple = menu.Append(-1, ”Simple menu item”)<br />
menu.AppendSeparator()<br />
exit = menu.Append(-1, ”Exit”)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnSimple, simple)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnExit, exit)<br />
menuBar = wx.MenuBar()<br />
menuBar.Append(menu, ”Menu”)<br />
self.SetMenuBar(menuBar)<br />
def OnSimple(self, event):<br />
wx.MessageBox(“You selected the simple menu item”)<br />
def OnExit(self, event):<br />
self.Close()<br />
def OnAddItem(self, event):<br />
item = self.menu.Append(-1, self.txt.GetValue())<br />
302 / 565
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnNewItemSelected, item)<br />
def OnNewItemSelected(self, event):<br />
item = self.GetMenuBar().F<strong>in</strong>dItemById(event.GetId()) #<br />
text = item.GetText()<br />
wx.MessageBox(“You selected the ’%s’ item” % text)<br />
if __name__ == ”__ma<strong>in</strong>__”:<br />
app = wx.PySimpleApp()<br />
frame = MyFrame()<br />
frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
F<strong>in</strong>dItemById()<br />
<br />
wx.MenuBarwx.Menu<br />
wx.MenuBarwx.Menu<br />
wx.MenuBar<br />
wx.Frame.GetMenuBar()<br />
F<strong>in</strong>dMenu(title)<br />
wx.NOT_FOUND<br />
GetMenu()<br />
def F<strong>in</strong>dMenuInMenuBar(menuBar, title):<br />
pos = menuBar.F<strong>in</strong>dMenu(title)<br />
if pos == wx.NOT_FOUND:<br />
return None<br />
return menuBar.GetMenu(pos)<br />
F<strong>in</strong>dMenutitle<br />
&FileF<strong>in</strong>dMenu(“File”)<br />
<br />
10.4wx.MenuBar<br />
<br />
303 / 565
10.4 wx.MenuBar<br />
F<strong>in</strong>dMenuItem(menuStr<strong>in</strong>g,itemStr<strong>in</strong>g)menuStr<strong>in</strong>g<br />
itemStr<strong>in</strong>gwx.NOT_FOUND<br />
F<strong>in</strong>dItemById(id)<strong>wxPython</strong><br />
None<br />
GetHelpStr<strong>in</strong>g(id)<br />
SetHelpStr<strong>in</strong>g(id,helpStr<strong>in</strong>g)id<br />
get*""set*<br />
GetLabel(id)<br />
SetLabel(id, label)id<br />
get*""set*<br />
<br />
10.5 wx.Menu<br />
<br />
<br />
<br />
10.5 wx.Menu<br />
F<strong>in</strong>dItem(itemStr<strong>in</strong>g)itemStr<strong>in</strong>gwx.NOT_FOUND<br />
F<strong>in</strong>dItemById(id)<strong>wxPython</strong><br />
None<br />
F<strong>in</strong>dItemByPosition(pos)<br />
GetHelpStr<strong>in</strong>g(id)<br />
SetHelpStr<strong>in</strong>g(id,helpStr<strong>in</strong>g)<br />
GetLabel(id)<br />
SetLabel(id, label)<br />
10.2.2 <br />
<br />
<br />
<br />
304 / 565
10.5<br />
IsEnabled()Enable()<br />
10.5<br />
import wx<br />
ID_SIMPLE = wx.NewId()<br />
class MyFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, -1,<br />
”Enable/Disable Menu Example”)<br />
p = wx.Panel(self)<br />
self.btn = wx.Button(p, -1, ”Disable Item”, (20,20))<br />
self.B<strong>in</strong>d(wx.EVT_BUTTON, self.OnToggleItem, self.btn)<br />
menu = wx.Menu()<br />
menu.Append(ID_SIMPLE, ”Simple menu item”)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnSimple, id=ID_SIMPLE)<br />
menu.AppendSeparator()<br />
menu.Append(wx.ID_EXIT, ”Exit”)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnExit, id=wx.ID_EXIT)<br />
menuBar = wx.MenuBar()<br />
menuBar.Append(menu, ”Menu”)<br />
self.SetMenuBar(menuBar)<br />
def OnSimple(self, event):<br />
wx.MessageBox(“You selected the simple menu item”)<br />
def OnExit(self, event):<br />
self.Close()<br />
def OnToggleItem(self, event):<br />
menubar = self.GetMenuBar()<br />
enabled = menubar.IsEnabled(ID_SIMPLE)<br />
menubar.Enable(ID_SIMPLE, not enabled)<br />
305 / 565
self.btn.SetLabel(<br />
(enabled and ”Enable” or ”Disable”) + ” Item”)<br />
if __name__ == ”__ma<strong>in</strong>__”:<br />
app = wx.PySimpleApp()<br />
frame = MyFrame()<br />
frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
<br />
wx.MenuItem.IsEnabled()wx.MenuBar.IsEnabled(id)<br />
wx.Menu.IsEnabled(id)<strong>wxPython</strong><br />
True<br />
Falsewx.Menu<br />
wx.MenuItem<br />
<br />
<br />
wx.MenuBar.Enable(id, enable), wx.Menu.Enable(id,enable), wx.MenuItem.Enabl<br />
e(enable)enableTrueFalse<br />
Enable()IsEnabled()<br />
wx.MenuBarEnableTop(pos,enable)<br />
posenable<br />
10.2.3 <br />
10.3<br />
AcceleratedCtrl-A<br />
306 / 565
10.3<br />
<br />
<br />
10.6<br />
10.6<br />
import wx<br />
class MyFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, -1,<br />
”Accelerator Example”)<br />
p = wx.Panel(self)<br />
menu = wx.Menu()<br />
simple = menu.Append(-1, ”Simple &menu item”) # Creat<strong>in</strong>g a mnemonic<br />
accel = menu.Append(-1, ”&Accelerated\tCtrl-A”) # Creat<strong>in</strong>g an accelerator<br />
menu.AppendSeparator()<br />
exit = menu.Append(-1, ”E&xit”)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnSimple, simple)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnAccelerated, accel)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnExit, exit)<br />
menuBar = wx.MenuBar()<br />
307 / 565
menuBar.Append(menu, ”&Menu”)<br />
self.SetMenuBar(menuBar)<br />
acceltbl = wx.AcceleratorTable( [ #Us<strong>in</strong>g an accelerator table<br />
(wx.ACCEL_CTRL, ord(‘Q’), exit.GetId())<br />
])<br />
self.SetAcceleratorTable(acceltbl)<br />
def OnSimple(self, event):<br />
wx.MessageBox(“You selected the simple menu item”)<br />
def OnAccelerated(self, event):<br />
wx.MessageBox(“You selected the accelerated menu item”)<br />
def OnExit(self, event):<br />
self.Close()<br />
if __name__ == ”__ma<strong>in</strong>__”:<br />
app = wx.PySimpleApp()<br />
frame = MyFrame()<br />
frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
<strong>wxPython</strong>mnemonicsaccelerator<br />
<br />
<br />
<br />
<br />
&&File, &EditMa&cros<br />
&&&&&<br />
<br />
W<strong>in</strong>dowsalt<br />
<br />
<br />
308 / 565
<strong>wxPython</strong><br />
<br />
<br />
<br />
\t\tAlt, Ctrl, Shift<br />
+-New\tctrl-n, SaveAs<br />
\tctrl-shift-s+-<br />
<br />
F1~F1210.6<br />
<br />
<strong>wxPython</strong><br />
menubar.F<strong>in</strong>dMenuItem(“File”, ”SaveAs”)<br />
Save asSave &As\tctrl-shift-s<br />
wx.AccleratorTable<br />
wx.AccelratorEntry<br />
wx.AcceleratorTable<br />
10.6<strong>wxPython</strong><br />
(wx.ACCEL_CTRL, ord(‘Q’)exit.GetId())wx.AcceleratorEntry<br />
wx.AcceleratorEntry<br />
wx.AcceleratorEntry(flags, keyCode, cmd)<br />
flags<br />
wx.ACCEL_ALT, wx.ACCEL_CTRL, wxACCEL_NORMAL<br />
, wx.ACCEL_SHIFT<br />
keyCode<br />
ASCIIwxWidgetsKeycodescmd<br />
<strong>wxPython</strong><br />
10.6<br />
<br />
309 / 565
10.6 <br />
<br />
<br />
del Delete<br />
delete Delete<br />
down Down arrow<br />
end End<br />
enter Enter<br />
esc Escape<br />
escape Escape<br />
home Home<br />
<strong>in</strong>s Insert<br />
<strong>in</strong>sert Insert<br />
left Left arrow<br />
pgdn Page down<br />
pgup Page Up<br />
return Enter<br />
right Right arrow<br />
space Space bar<br />
tab Tab<br />
up Up arrow<br />
10.2.4 <br />
<br />
<br />
<br />
<br />
10.4<br />
<br />
310 / 565
10.4<br />
<br />
<br />
<br />
10.7<br />
<br />
10.7 <br />
import wx<br />
class MyFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, -1,<br />
”Toggle Items Example”)<br />
p = wx.Panel(self)<br />
menuBar = wx.MenuBar()<br />
menu = wx.Menu()<br />
exit = menu.Append(-1, ”Exit”)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnExit, exit)<br />
menuBar.Append(menu, ”Menu”)<br />
menu = wx.Menu()<br />
menu.AppendCheckItem(-1, ”Check Item 1”)<br />
menu.AppendCheckItem(-1, ”Check Item 2”)<br />
311 / 565
menu.AppendCheckItem(-1, ”Check Item 3”)<br />
menu.AppendSeparator()<br />
menu.AppendRadioItem(-1, ”Radio Item 1”)<br />
menu.AppendRadioItem(-1, ”Radio Item 2”)<br />
menu.AppendRadioItem(-1, ”Radio Item 3”)<br />
menuBar.Append(menu, ”Toggle Items”)<br />
self.SetMenuBar(menuBar)<br />
def OnExit(self, event):<br />
self.Close()<br />
if __name__ == ”__ma<strong>in</strong>__”:<br />
app = wx.PySimpleApp()<br />
frame = MyFrame()<br />
frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
<br />
AppendCheckItem(id, item, helpStr<strong>in</strong>g=””)<br />
Append()<strong>wxPython</strong><br />
<br />
PrependCheckItem(id,item, helpStr<strong>in</strong>g=””)<br />
InsertCheckItem(pos, id, item, helpStr<strong>in</strong>g=””)<br />
<br />
AppendRadioItem(id,item,helpStr<strong>in</strong>g=””)<br />
PrependRadioItem(id,item, helpStr<strong>in</strong>g=””)<br />
InsertRadioItem(pos, id, item, helpStr<strong>in</strong>g=””)<br />
<br />
<br />
<br />
Append()Append()k<strong>in</strong>d<br />
wx.ITEM_CHECK, wx.ITEM_NORMAL, wx.ITEM_RADIO<br />
wx.ITEM_SEPARATOR<br />
<br />
k<strong>in</strong>dwx.ITEM_SEPARATOR<br />
idwx.ID_SEPARATOR<br />
312 / 565
wx.MenuItem<br />
k<strong>in</strong>d<br />
AppendItem(), PrependItem(), InsertItem()<br />
IsCheckable()<br />
TrueIsChecked()<br />
TrueCheck(check)<br />
checkCheck(check)<br />
<br />
IsChecked(id)<br />
idCheck(id, check)<br />
check<br />
10.3 <br />
<br />
<br />
<br />
10.3.1 <br />
<br />
<br />
<br />
10.5<br />
313 / 565
10.5<br />
10.810.5<br />
10.8 <br />
import wx<br />
class MyFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, -1,<br />
”Sub-menu Example”)<br />
p = wx.Panel(self)<br />
menu = wx.Menu()<br />
submenu = wx.Menu()<br />
submenu.Append(-1, ”Sub-item 1”)<br />
submenu.Append(-1, ”Sub-item 2”)<br />
menu.AppendMenu(-1, ”Sub-menu”, submenu)#<br />
menu.AppendSeparator()<br />
exit = menu.Append(-1, ”Exit”)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnExit, exit)<br />
menuBar = wx.MenuBar()<br />
menuBar.Append(menu, ”Menu”)<br />
self.SetMenuBar(menuBar)<br />
314 / 565
def OnExit(self, event):<br />
self.Close()<br />
if __name__ == ”__ma<strong>in</strong>__”:<br />
app = wx.PySimpleApp()<br />
frame = MyFrame()<br />
frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
10.8<br />
wx.Menu<br />
AppendMenu(id, text, submenu, helpStr)<br />
Append()id<br />
<strong>wxPython</strong>text<br />
submenuhelpStr<br />
PrependMenu(id,text, submenu, helpStr)<br />
InsertMenu(pos, text, submenu, helpStr)<br />
<br />
<br />
<br />
<strong>wxPython</strong><br />
<br />
<br />
10.3.2 <br />
<br />
<br />
10.6<br />
315 / 565
10.6<br />
<br />
10.9<br />
10.9 <br />
import wx<br />
class MyFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, -1,<br />
”Popup Menu Example”)<br />
self.panel = p = wx.Panel(self)<br />
menu = wx.Menu()<br />
exit = menu.Append(-1, ”Exit”)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnExit, exit)<br />
menuBar = wx.MenuBar()<br />
menuBar.Append(menu, ”Menu”)<br />
self.SetMenuBar(menuBar)<br />
wx.StaticText(p, -1,<br />
”Right-click on the panel to show a popup menu”,<br />
(25,25))<br />
self.popupmenu = wx.Menu()#<br />
for text <strong>in</strong> ”one two three four five”.split():#<br />
316 / 565
item = self.popupmenu.Append(-1, text)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnPopupItemSelected, item)<br />
p.B<strong>in</strong>d(wx.EVT_CONTEXT_MENU, self.OnShowPopup)#<br />
<br />
def OnShowPopup(self, event):#<br />
pos = event.GetPosition()<br />
pos = self.panel.ScreenToClient(pos)<br />
self.panel.PopupMenu(self.popupmenu, pos)<br />
def OnPopupItemSelected(self, event):<br />
item = self.popupmenu.F<strong>in</strong>dItemById(event.GetId())<br />
text = item.GetText()<br />
wx.MessageBox(“You selected item ’%s’” % text)<br />
def OnExit(self, event):<br />
self.Close()<br />
if __name__ == ”__ma<strong>in</strong>__”:<br />
app = wx.PySimpleApp()<br />
frame = MyFrame()<br />
frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
for<br />
self.popupmenu<br />
OnShowPopup()wx.EVT_CONTEXT_MENU<br />
W<strong>in</strong>dowsGTK<br />
Mac OScontrol<br />
OnShowPopup()<br />
<br />
wx.EVT_CONTEXT_MENU<br />
<br />
ScreenToClient()<br />
317 / 565
PopupMenu(menu, pos)<br />
PopupMenuXY(menu, x, y)PopupMenu<br />
Esc<br />
<br />
EVT_MENUPopupMenu<br />
PopupMenu<br />
<br />
wx.Menu.SetTitle(title)wx.Menu.GetTitle()<br />
10.3.3 <br />
<br />
W<strong>in</strong>dows<br />
10.7<br />
10.7<br />
10.10W<strong>in</strong>dows<br />
‘wxMSW’wx.PlatformInfo<br />
10.10 <br />
import wx<br />
class MyFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
318 / 565
wx.Frame.__<strong>in</strong>it__(self, None, -1,<br />
”Fancier Menu Example”)<br />
p = wx.Panel(self)<br />
menu = wx.Menu()<br />
bmp = wx.Bitmap(“open.png”, wx.BITMAP_TYPE_PNG)<br />
item = wx.MenuItem(menu, -1, ”Has Open Bitmap”)<br />
item.SetBitmap(bmp)#<br />
menu.AppendItem(item)<br />
if True or ’wxMSW’ <strong>in</strong> wx.PlatformInfo:<br />
font = wx.SystemSett<strong>in</strong>gs.GetFont(<br />
wx.SYS_DEFAULT_GUI_FONT)<br />
font.SetWeight(wx.BOLD)<br />
item = wx.MenuItem(menu, -1, ”Has Bold Font”)<br />
item.SetFont(font)#<br />
menu.AppendItem(item)<br />
item = wx.MenuItem(menu, -1, ”Has Red Text”)<br />
item.SetTextColour(“red”)#<br />
menu.AppendItem(item)<br />
menu.AppendSeparator()<br />
exit = menu.Append(-1, ”Exit”)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnExit, exit)<br />
menuBar = wx.MenuBar()<br />
menuBar.Append(menu, ”Menu”)<br />
self.SetMenuBar(menuBar)<br />
def OnExit(self, event):<br />
self.Close()<br />
if __name__ == ”__ma<strong>in</strong>__”:<br />
app = wx.PySimpleApp()<br />
frame = MyFrame()<br />
frame.Show()<br />
319 / 565
app.Ma<strong>in</strong>Loop()<br />
<br />
W<strong>in</strong>dowsW<strong>in</strong>dows)bitmapGetBitmap()<br />
wx.Bitmapset*<br />
SetBitmap(bmp)<br />
W<strong>in</strong>dows<br />
SetBitmaps(checked, unchecked=wx.NullBitmap)<br />
<br />
checked<br />
W<strong>in</strong>dws<br />
10.7<br />
<br />
10.7 <br />
GetBackgroundColour()<br />
SetBackgroundColour(colour)wx.Colourset*<br />
<strong>wxPython</strong><br />
GetFont()<br />
SetFont(font)wx.Font<br />
GetTextColour()<br />
SetTextColour(colour)<br />
<br />
<br />
<br />
10.4 <br />
<br />
<br />
<br />
320 / 565
10.4.1 <br />
1015<br />
<br />
<br />
10.4.2 <br />
<br />
——<br />
<br />
<br />
<br />
FILE<br />
newopensavepr<strong>in</strong>t<br />
quit<br />
<br />
EDITundocutcopy<br />
pastef<strong>in</strong>d<br />
HELPw<strong>in</strong>dows<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
30~40<br />
<br />
<br />
...<br />
<br />
321 / 565
10.8<br />
10.8<br />
<br />
Ctrl-a<br />
Ctrl-c<br />
Ctrl-f<br />
Ctrl-g<br />
Ctrl-n<br />
Ctrl-o<br />
Ctrl-p<br />
Ctrl-q<br />
Ctrl-s<br />
Ctrl-v<br />
Ctrl-w<br />
Ctrl-x<br />
Ctrl-z<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
RedoCtrlyAlt-z<br />
<br />
<br />
<br />
<br />
<br />
<br />
fancy mode on<br />
<br />
fancy<br />
Turn fancy mode offfancy<br />
<br />
<br />
toggle fancy mode<br />
switch fancy mode (now on)<br />
322 / 565
10.5 <br />
·<strong>wxPython</strong><br />
wx.MenuBar<br />
wx.Menuwx.MenuItem<br />
<br />
<br />
<br />
<br />
·wx.EVT_MENU<br />
<br />
wx.EVT_MENU<br />
wx.EVT_MENU_RANGE<br />
<br />
·ID<br />
<br />
·<br />
wx.Menu<br />
<br />
·<br />
·<br />
<br />
<br />
323 / 565
·wx.EVT_CONTEXT_MENU<br />
PopupMenu()<br />
·W<strong>in</strong>dows<br />
<br />
324 / 565
11 sizer<br />
<br />
·sizer<br />
·sizer<br />
·sizergrid<br />
·box sizer<br />
·sizer<br />
<br />
<br />
<br />
sizersizer<br />
sizer<br />
sizersizer<br />
<br />
sizersizer<br />
<br />
sizersizer<br />
sizersizer——<br />
grid bagbox<br />
11.1 sizer<br />
<strong>wxPython</strong> sizer<br />
sizer<br />
sizerwx.Sizer<strong>wxPython</strong>5<br />
sizer11.1sizersizer<br />
11.1 <strong>wxPython</strong>sizer<br />
Grid<br />
<br />
Flex gridgrid sizer<br />
<br />
325 / 565
Grid baggrid sizer<br />
<br />
Box<br />
<br />
Static boxbox sizer<br />
gridbox,<strong>wxPython</strong><br />
gridbox<br />
sizersizer<br />
<br />
<br />
sizer<br />
<strong>wxPython</strong>sizer<br />
sizer<br />
<br />
·sizersizerwx.W<strong>in</strong>dow<br />
SetSizer(sizer)wx.W<strong>in</strong>dow<br />
<strong>wxPython</strong>sizersizer<br />
<br />
·sizer<br />
sizer<br />
sizerAdd()Add()<br />
<br />
·sizersizer<br />
wx.W<strong>in</strong>dowFit()sizer<br />
Fit(w<strong>in</strong>dow)sizer<br />
Fit()sizer<br />
FitInside()<br />
——<br />
<strong>wxPython</strong><br />
sizersizer<br />
grid sizer<br />
sizergrid sizergrid sizer<br />
326 / 565
sizer<br />
11.2 sizergrid sizer<br />
<br />
sizer11.1<br />
——<br />
<br />
11.1 <br />
import wx<br />
class BlockW<strong>in</strong>dow(wx.Panel):<br />
def __<strong>in</strong>it__(self, parent, ID=-1, label=””,<br />
pos=wx.DefaultPosition, size=(100, 25)):<br />
wx.Panel.__<strong>in</strong>it__(self, parent, ID, pos, size,<br />
wx.RAISED_BORDER, label)<br />
self.label = label<br />
self.SetBackgroundColour(“white”)<br />
self.SetM<strong>in</strong>Size(size)<br />
self.B<strong>in</strong>d(wx.EVT_PAINT, self.OnPa<strong>in</strong>t)<br />
def OnPa<strong>in</strong>t(self, evt):<br />
sz = self.GetClientSize()<br />
dc = wx.Pa<strong>in</strong>tDC(self)<br />
w,h = dc.GetTextExtent(self.label)<br />
dc.SetFont(self.GetFont())<br />
dc.DrawText(self.label, (sz.width-w)/2, (sz.height-h)/2)<br />
sizer<br />
grid sizer<br />
11.2.1 grid sizer<br />
<strong>wxPython</strong>sizergridgrid sizer<br />
sizer<br />
<br />
327 / 565
11.1<br />
3*3<br />
11.1<br />
grid sizer<br />
11.2<br />
<br />
11.2<br />
11.211.111.2<br />
11.2 grid sizer<br />
import wx<br />
from blockw<strong>in</strong>dow import BlockW<strong>in</strong>dow<br />
labels = ”one two three four five six seven eight n<strong>in</strong>e”.split()<br />
328 / 565
class GridSizerFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, -1, ”Basic Grid Sizer”)<br />
sizer = wx.GridSizer(rows=3, cols=3, hgap=5, vgap=5)#grid sizer<br />
for label <strong>in</strong> labels:<br />
bw = BlockW<strong>in</strong>dow(self, label=label)<br />
sizer.Add(bw, 0, 0)#sizer<br />
self.SetSizer(sizer)#sizer<br />
self.Fit()<br />
app = wx.PySimpleApp()<br />
GridSizerFrame().Show()<br />
app.Ma<strong>in</strong>Loop()<br />
11.2grid sizerwx.GridSizer<br />
grid sizer<br />
wx.GridSizer(rows, cols, vgap, hgap)<br />
rowscols——<br />
0<br />
sizerwx.GridSizer(2, 0, 0, 0)sizer<br />
<br />
vgaphgapvgap<br />
hgapvgap<br />
rows, cols, vgap, hgapget*set*——<br />
GetRows(), SetRows(rows), GetCols(),SetCols(cols), GetVGap(), SetVGap(gap), Get<br />
HGap(), SetHGap(gap) <br />
grid sizerFit()<br />
<br />
grid——<br />
<br />
grid sizer<br />
grid sizergrid<br />
flex grid sizergrid bag sizer<br />
329 / 565
11.2.2 sizer<br />
sizer<br />
sizer<br />
<br />
grid sizer<br />
sizer<br />
<br />
<br />
<br />
sizerAdd()<br />
sizer“sizer”<br />
sizer<br />
Add()<br />
Add(w<strong>in</strong>dow, proportion=0, flag=0, border=0, userData=None)<br />
Add(sizer, proportion=0, flag=0, border=0, userData=None)<br />
Add(size, proportion=0, flag=0, border=0, userData=None)<br />
<br />
sizersizer——<br />
box sizersizerwx.Size<br />
sizer<br />
box sizersizer<br />
<br />
sizersizer<br />
proportionbox sizer<br />
box sizer<br />
flag<br />
flagborder<br />
sizeruserData<br />
sizer<br />
330 / 565
sizer<strong>in</strong>sert()<br />
<br />
Insert(<strong>in</strong>dex, w<strong>in</strong>dow, proportion=0, flag=0, border=0, userData=None)<br />
Insert(<strong>in</strong>dex, sizer, proportion=0, flag=0, border=0, userData=None)<br />
Insert(<strong>in</strong>dex, size, proportion=0, flag=0, border=0, userData=None)<br />
<br />
sizersizer<br />
<br />
Prepend(w<strong>in</strong>dow, proportion=0, flag=0, border=0, userData=None)<br />
Prepend(sizer, proportion=0, flag=0, border=0, userData=None)<br />
Prepend(size, proportion=0, flag=0, border=0, userData=None)<br />
11.3<br />
11.311.1Add()Prepend()<br />
sizersizer<br />
sizerLayout()sizer<br />
Detach()<br />
sizerDetach()sizer<br />
Detach()<br />
sizer<br />
Detach()<br />
Detach(w<strong>in</strong>dow)<br />
331 / 565
Detach(sizer)<br />
Detach(<strong>in</strong>dex)<br />
Detach()<br />
——sizerfalse<br />
Detach()<br />
<br />
sizerLayout()<br />
<br />
sizerwx.W<strong>in</strong>dow<br />
GetConta<strong>in</strong><strong>in</strong>gSizer()sizer<br />
None<br />
11.2.3 sizer<br />
sizersizer<br />
<br />
sizer<br />
<br />
sizersizer<br />
sizer<br />
sizerflag<br />
11.4<br />
grid sizer<br />
332 / 565
11.4<br />
11.311.4sizer<br />
<br />
11.3 grid sizer<br />
import wx<br />
from blockw<strong>in</strong>dow import BlockW<strong>in</strong>dow<br />
labels = ”one two three four five six seven eight n<strong>in</strong>e”.split()<br />
#<br />
flags = {“one”: wx.ALIGN_BOTTOM, ”two”: wx.ALIGN_CENTER,<br />
”four”: wx.ALIGN_RIGHT, ”six”: wx.EXPAND, ”seven”: wx.EXPAND,<br />
”eight”: wx.SHAPED}<br />
class TestFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, -1, ”GridSizer Resiz<strong>in</strong>g”)<br />
sizer = wx.GridSizer(rows=3, cols=3, hgap=5, vgap=5)<br />
for label <strong>in</strong> labels:<br />
bw = BlockW<strong>in</strong>dow(self, label=label)<br />
flag = flags.get(label, 0)<br />
sizer.Add(bw, 0, flag)<br />
self.SetSizer(sizer)<br />
self.Fit()<br />
app = wx.PySimpleApp()<br />
TestFrame().Show()<br />
333 / 565
app.Ma<strong>in</strong>Loop()<br />
“one,” “two,” “four”<br />
wx.ALIGN_BOTTOM, wx.ALIGN_CENTER, and wx.ALIGN_RIGHT<br />
“three”<br />
“six”“seven”wx.EXPAND<br />
sizer“eight”wx.SHAPED<br />
<br />
11.2flag<br />
11.2 <br />
wx.ALIGN_BOTTOM<br />
wx.ALIGN_CENTER<br />
<br />
wx.ALIGN_CENTER_HORIZONTAL<br />
wx.ALIGN_CENTER_VERTICAL <br />
wx.ALIGN_LEFT<br />
wx.ALIGN_TOP<br />
wx.EXPAND<br />
wx.FIXED_MINSIZE<br />
wx.GROWwx.EXPAND<br />
wx.SHAPED<br />
<br />
|<br />
wx.ALIGN_TOP | wx.ALIGN_RIGHT<br />
wx.ALIGN_TOP | wx.ALIGN_BOTTOM<br />
0<br />
<br />
334 / 565
sizer<br />
GetSize() GetPosition()sizer——<br />
sizersizersizer<br />
SetDimension(x, y, width, height)<br />
sizersizer<br />
<br />
11.2.4 sizer<br />
sizersizer<br />
sizer<br />
sizer<br />
<br />
<br />
11.5<br />
<br />
11.5<br />
11.4grid<br />
SetM<strong>in</strong>Size()<br />
11.4 grid sizer<br />
import wx<br />
from blockw<strong>in</strong>dow import BlockW<strong>in</strong>dow<br />
labels = ”one two three four five six seven eight n<strong>in</strong>e”.split()<br />
class TestFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
335 / 565
wx.Frame.__<strong>in</strong>it__(self, None, -1, ”GridSizer Test”)<br />
sizer = wx.GridSizer(rows=3, cols=3, hgap=5, vgap=5)<br />
for label <strong>in</strong> labels:<br />
bw = BlockW<strong>in</strong>dow(self, label=label)<br />
sizer.Add(bw, 0, 0)<br />
center = self.F<strong>in</strong>dW<strong>in</strong>dowByName(“five”)<br />
center.SetM<strong>in</strong>Size((150,50))<br />
self.SetSizer(sizer)<br />
self.Fit()<br />
app = wx.PySimpleApp()<br />
TestFrame().Show()<br />
app.Ma<strong>in</strong>Loop()<br />
sizer<br />
“<br />
”sizer<br />
<br />
SetM<strong>in</strong>Size(width, height)<br />
SetSizeH<strong>in</strong>ts(m<strong>in</strong>W, m<strong>in</strong>H, maxW, maxH)——<br />
<br />
<br />
sizersizer<br />
<br />
<br />
<br />
GetM<strong>in</strong>Size()sizersizer<br />
SetM<strong>in</strong>Size(width,height)<br />
wx.Size——SetM<strong>in</strong>Size(size)<strong>wxPython</strong><br />
wx.SizeGetM<strong>in</strong>Size()<br />
<br />
sizersizer<br />
SetItemM<strong>in</strong>Size()<br />
SetItemM<strong>in</strong>Size(w<strong>in</strong>dow, size)<br />
SetItemM<strong>in</strong>Size(sizer, size)<br />
SetItemM<strong>in</strong>Size(<strong>in</strong>dex, size)<br />
336 / 565
w<strong>in</strong>dowsizersizer<br />
sizer<strong>in</strong>dexsizer<br />
sizewx.Size()sizer<br />
<br />
sizer<br />
SetSizeH<strong>in</strong>ts()<br />
11.2.5 sizer<br />
<strong>wxPython</strong> sizer<br />
sizer<br />
sizer<br />
<br />
11.610<br />
<br />
<br />
11.6<br />
11.511.6grid sizer<br />
Add()10<br />
11.5 grid sizer<br />
import wx<br />
from blockw<strong>in</strong>dow import BlockW<strong>in</strong>dow<br />
labels = ”one two three four five six seven eight n<strong>in</strong>e”.split()<br />
#<br />
flags = {“one”: wx.BOTTOM, ”two”: wx.ALL, ”three”: wx.TOP,<br />
337 / 565
”four”: wx.LEFT, ”five”: wx.ALL, ”six”: wx.RIGHT,<br />
”seven”: wx.BOTTOM | wx.TOP, ”eight”: wx.ALL,<br />
”n<strong>in</strong>e”: wx.LEFT | wx.RIGHT}<br />
class TestFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, -1, ”GridSizer Borders”)<br />
sizer = wx.GridSizer(rows=3, cols=3, hgap=5, vgap=5)<br />
for label <strong>in</strong> labels:<br />
bw = BlockW<strong>in</strong>dow(self, label=label)<br />
flag = flags.get(label, 0)<br />
sizer.Add(bw, 0, flag, 10)#<br />
self.SetSizer(sizer)<br />
self.Fit()<br />
app = wx.PySimpleApp()<br />
TestFrame().Show()<br />
app.Ma<strong>in</strong>Loop()<br />
sizer<br />
sizerflagswx.ALL<br />
<br />
wx.BOTTOM, wx.LEFT, wx.RIGHT, wx.TOP<br />
wx.RIGHT | wx.BOTTOM<br />
flags<br />
<br />
flags<br />
bordersizer<br />
5<br />
sizer.Add(widget, 0, wx.ALL | wx.EXPAND, 5)<br />
5<br />
<br />
338 / 565
11.3 sizer<br />
sizersizer<br />
flex grid sizergrid bag sizergrid<br />
boxstatic box sizer<br />
11.3.1 flex grid sizer<br />
flex grid sizergrid sizergrid sizer<br />
<br />
1<br />
2<br />
<br />
3<br />
<br />
11.7flex grid sizer9<br />
<br />
11.7<br />
11.511.5<br />
flex grid sizer<br />
<br />
“four”“six”<br />
“five”“two”“seven”<br />
“one,” “three,” “seven,” “n<strong>in</strong>e”<br />
<br />
11.8flex grid sizer——<br />
<br />
339 / 565
11.8<br />
11.611.8<br />
11.6 flex grid sizer<br />
import wx<br />
from blockw<strong>in</strong>dow import BlockW<strong>in</strong>dow<br />
labels = ”one two three four five six seven eight n<strong>in</strong>e”.split()<br />
class TestFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, -1, ”FlexGridSizer”)<br />
sizer = wx.FlexGridSizer(rows=3, cols=3, hgap=5, vgap=5)<br />
for label <strong>in</strong> labels:<br />
bw = BlockW<strong>in</strong>dow(self, label=label)<br />
sizer.Add(bw, 0, 0)<br />
center = self.F<strong>in</strong>dW<strong>in</strong>dowByName(“five”)<br />
center.SetM<strong>in</strong>Size((150,50))<br />
self.SetSizer(sizer)<br />
self.Fit()<br />
app = wx.PySimpleApp()<br />
TestFrame().Show()<br />
app.Ma<strong>in</strong>Loop()<br />
flex grid sizerwx.FlexGridSizerwx.FlexGridSizer<br />
wx.GridSizerwx.GridSizerwx.FlexGridSizer<br />
<br />
340 / 565
wx.FlexGridSizer(rows, cols, vgap, hgap)<br />
sizer<br />
sizer<br />
AddGrowableCol(idx, proportion=0)<br />
AddGrowableRow(idx, proportion=0)<br />
sizer<br />
<br />
proportion<br />
proportion<br />
proportion<br />
212/31/311.9<br />
proportionalflex grid sizer<br />
251<br />
11.9<br />
<br />
<br />
sizerwx.EXPAND11.711.9<br />
<br />
11.7<br />
import wx<br />
from blockw<strong>in</strong>dow import BlockW<strong>in</strong>dow<br />
341 / 565
labels = ”one two three four five six seven eight n<strong>in</strong>e”.split()<br />
class TestFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, -1, ”Resiz<strong>in</strong>g Flex Grid Sizer”)<br />
sizer = wx.FlexGridSizer(rows=3, cols=3, hgap=5, vgap=5)<br />
for label <strong>in</strong> labels:<br />
bw = BlockW<strong>in</strong>dow(self, label=label)<br />
sizer.Add(bw, 0, 0)<br />
center = self.F<strong>in</strong>dW<strong>in</strong>dowByName(“five”)<br />
center.SetM<strong>in</strong>Size((150,50))<br />
sizer.AddGrowableCol(0, 1)<br />
sizer.AddGrowableCol(1, 2)<br />
sizer.AddGrowableCol(2, 1)<br />
sizer.AddGrowableRow(0, 1)<br />
sizer.AddGrowableRow(1, 5)<br />
sizer.AddGrowableRow(2, 1)<br />
self.SetSizer(sizer)<br />
self.Fit()<br />
app = wx.PySimpleApp()<br />
TestFrame().Show()<br />
app.Ma<strong>in</strong>Loop()<br />
<br />
<br />
flex grid sizer<br />
AddGrowable*flex grid<br />
SetFlexibleDirection(direction)<br />
direction<br />
wx.HORIZONTAL, wx.VERTICAL, wx.BOTH <br />
SetNonFlexibleGrowMode(mode)<br />
SetFlexibleDirection(wx.HORIZONTAL)<br />
AddGrowableCol()SetNonFlexibleGrowMode()<br />
11.3mode<br />
342 / 565
11.3<br />
wx.FLEX_GROWMODE_ALLflex gridSetFlexibleDirection*<br />
AddGrowable*——<br />
<br />
<br />
wx.FLEX_GROWMODE_NONESetFlexibleDirection*<br />
<br />
wx.FLEX_GROWMODE_SPECIFIEDSetFlexibleDirection*<br />
sizer<br />
<br />
SetFlexibleDirectionSetNonFlexibleGrowMode<br />
GetFlexibleDirection()GetNonFlexibleGrowMode()<br />
<br />
AddGrowableCol()AddGrowableRow()<br />
11.3.2 grid bag sizer<br />
grid bag sizerflex grid sizergrid bag sizer<br />
<br />
1<br />
2HTML<br />
<br />
11.10<br />
11.10grid bag sizer<br />
<br />
11.811.10Add()<br />
<br />
343 / 565
11.8 Grid bag sizer<br />
import wx<br />
from blockw<strong>in</strong>dow import BlockW<strong>in</strong>dow<br />
labels = ”one two three four five six seven eight n<strong>in</strong>e”.split()<br />
class TestFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, -1, ”GridBagSizer Test”)<br />
sizer = wx.GridBagSizer(hgap=5, vgap=5)<br />
for col <strong>in</strong> range(3):<br />
for row <strong>in</strong> range(3):<br />
bw = BlockW<strong>in</strong>dow(self, label=labels[row*3 + col])<br />
sizer.Add(bw, pos=(row,col))<br />
# <br />
bw = BlockW<strong>in</strong>dow(self, label=”span 3 rows”)<br />
sizer.Add(bw, pos=(0,3), span=(3,1), flag=wx.EXPAND)<br />
# <br />
bw = BlockW<strong>in</strong>dow(self, label=”span all columns”)<br />
sizer.Add(bw, pos=(3,0), span=(1,4), flag=wx.EXPAND)<br />
# <br />
sizer.AddGrowableCol(3)<br />
sizer.AddGrowableRow(3)<br />
self.SetSizer(sizer)<br />
self.Fit()<br />
app = wx.PySimpleApp()<br />
TestFrame().Show()<br />
app.Ma<strong>in</strong>Loop()<br />
344 / 565
grid bag sizerwx.GridBagSizerwx.GridBagSizer<br />
wx.FlexGridSizerflex grid sizergrid bag sizer<br />
<br />
wx.GridBagSizer<br />
wx.GridBagSizer(vgap=0, hgap=0)<br />
grid bag sizer<br />
——sizer<br />
<br />
grid bag sizerAdd()sizer<br />
1 Add(w<strong>in</strong>dow, pos, span=wx.DefaultSpan, flag=0, border=0,<br />
userData=None)<br />
2 Add(sizer, pos, span=wx.DefaultSpan, flag=0, border=0,<br />
userData=None)<br />
3 Add(size, pos, span=wx.DefaultSpan, flag=0, border=0,<br />
userData=None)<br />
4 AddItem(item)<br />
sizer<br />
w<strong>in</strong>dow, sizer, size, flag, border, userDatasizer<br />
possizerpos<br />
wx.GBPosition<strong>wxPython</strong><br />
(,)grid bag(0,0)<br />
span<br />
wx.GBSpan<strong>wxPython</strong>(<br />
)(1,1)<br />
<br />
Add(widget, (1, 0), (3, 2))<br />
0<br />
345 / 565
Additemitemwx.GBSizerItem<br />
grid bag sizer<br />
wx.GBSizerItem<br />
grid bag sizerAdd()wx.GBSizerItem<br />
get*GetW<strong>in</strong>dow()<br />
<br />
grid bag sizer<br />
sizer<br />
11.4<br />
grid bag sizer<br />
11.4 Grid bag sizer <br />
CheckForIntersection(item,excludeItem=None)<br />
CheckForIntersection(pos,span, excludeItem=None)<br />
sizer<br />
TrueexcludeItem<br />
poswx.GBPositionspan<br />
wx.GPSpan<br />
F<strong>in</strong>dItem(w<strong>in</strong>dow)<br />
F<strong>in</strong>dItem(sizer)sizerwx.GBSizerItem<br />
sizergrid bagNonesizer<br />
F<strong>in</strong>dItemAtPo<strong>in</strong>t(pt)ptwx.Po<strong>in</strong>t<br />
Pythonwx.GBSizerItem <br />
sizerNone<br />
F<strong>in</strong>dItemAtPosition(pos)wx.GBSizerItem<br />
poswx.GBPositionPythonsizer<br />
None<br />
F<strong>in</strong>dItemWithData(userData)grid baguserData<br />
wx.GBSizerItem<br />
Grid baggrid bag<br />
GetCellSize(row, col)<br />
sizer<br />
GetEmptyCellSize()<br />
SetEmptyCellSize(sz)szwx.Size<br />
Python<br />
346 / 565
GetItemPosition()GetItemSpan()grid bag<br />
sizer<br />
sizerAdd()grid bag<br />
get*set*<br />
SetItemPosition(w<strong>in</strong>dow, pos)SetItemSpan(w<strong>in</strong>dow, span)<br />
w<strong>in</strong>dow,sizer,<strong>in</strong>dexPython<br />
wx.GBPositionwx.GBSpan<br />
11.3.3 box sizer<br />
box sizer<strong>wxPython</strong>sizersizer<br />
box sizer<br />
sizer<br />
sizer<br />
<br />
sizersizer<br />
11.11-11.14box sizer<br />
sizer<br />
11.11box sizer11.12box sizer<br />
11.11<br />
11.11<br />
11.12<br />
347 / 565
11.13sizer<br />
11.14sizer<br />
<br />
11.13<br />
11.14<br />
sizer11.9<br />
348 / 565
11.9 box sizer<br />
import wx<br />
from blockw<strong>in</strong>dow import BlockW<strong>in</strong>dow<br />
labels = ”one two three four”.split()<br />
class TestFrame(wx.Frame):<br />
title = ”none”<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, -1, self.title)<br />
sizer = self.CreateSizerAndW<strong>in</strong>dows()<br />
self.SetSizer(sizer)<br />
self.Fit()<br />
class VBoxSizerFrame(TestFrame):<br />
title = ”Vertical BoxSizer”<br />
def CreateSizerAndW<strong>in</strong>dows(self):<br />
sizer = wx.BoxSizer(wx.VERTICAL)<br />
for label <strong>in</strong> labels:<br />
bw = BlockW<strong>in</strong>dow(self, label=label, size=(200,30))<br />
sizer.Add(bw, flag=wx.EXPAND)<br />
return sizer<br />
class HBoxSizerFrame(TestFrame):<br />
title = ”Horizontal BoxSizer”<br />
def CreateSizerAndW<strong>in</strong>dows(self):<br />
sizer = wx.BoxSizer(wx.HORIZONTAL)<br />
for label <strong>in</strong> labels:<br />
bw = BlockW<strong>in</strong>dow(self, label=label, size=(75,30))<br />
sizer.Add(bw, flag=wx.EXPAND)<br />
return sizer<br />
class VBoxSizerStretchableFrame(TestFrame):<br />
title = ”Stretchable BoxSizer”<br />
def CreateSizerAndW<strong>in</strong>dows(self):<br />
349 / 565
sizer = wx.BoxSizer(wx.VERTICAL)<br />
for label <strong>in</strong> labels:<br />
bw = BlockW<strong>in</strong>dow(self, label=label, size=(200,30))<br />
sizer.Add(bw, flag=wx.EXPAND)<br />
# Add an item that takes all the free space<br />
bw = BlockW<strong>in</strong>dow(self, label=”gets all free space”, size=(200,30))<br />
sizer.Add(bw, 1, flag=wx.EXPAND)<br />
return sizer<br />
class VBoxSizerMultiProportionalFrame(TestFrame):<br />
title = ”Proportional BoxSizer”<br />
def CreateSizerAndW<strong>in</strong>dows(self):<br />
sizer = wx.BoxSizer(wx.VERTICAL)<br />
for label <strong>in</strong> labels:<br />
bw = BlockW<strong>in</strong>dow(self, label=label, size=(200,30))<br />
sizer.Add(bw, flag=wx.EXPAND)<br />
# Add an item that takes one share of the free space<br />
bw = BlockW<strong>in</strong>dow(self,<br />
label=”gets 1/3 of the free space”,<br />
size=(200,30))<br />
sizer.Add(bw, 1, flag=wx.EXPAND)<br />
# Add an item that takes 2 shares of the free space<br />
bw = BlockW<strong>in</strong>dow(self,<br />
label=”gets 2/3 of the free space”,<br />
size=(200,30))<br />
sizer.Add(bw, 2, flag=wx.EXPAND)<br />
return sizer<br />
app = wx.PySimpleApp()<br />
frameList = [VBoxSizerFrame, HBoxSizerFrame,<br />
VBoxSizerStretchableFrame,<br />
VBoxSizerMultiProportionalFrame]<br />
for klass <strong>in</strong> frameList:<br />
frame = klass()<br />
frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
350 / 565
ox sizerwx.BoxSizerwx.BoxSizerwx.Sizer<br />
wx.Sizerwx.BoxSizerwx.BoxSizer<br />
<br />
wx.BoxSizer(orient)<br />
orientsizerwx.VERTICAL<br />
wx.HORIZONTALbox sizer<br />
GetOrientation()orientbox sizer<br />
box sizer<br />
sizer<br />
box sizersizer<br />
proportionsizer<br />
wx.EXPANDsizer<br />
box sizerAdd()<br />
proportionsizer<br />
proportionbox sizer<br />
wx.EXPAND<br />
box sizerwx.EXPAND<br />
6.7<br />
<br />
box sizerflex grid sizer<br />
box sizersizerproportion<br />
——flex grid sizer<br />
0box sizer0<br />
wx.EXPAND<br />
box sizer<br />
<br />
0<br />
11.3.4 static box sizer<br />
static box sizerbox sizerstatic boxsizer<br />
11.15static box sizer<br />
351 / 565
11.15<br />
11.10<br />
sizer<br />
box sizerstatic box sizerbox sizer<br />
11.10 static box sizer<br />
import wx<br />
from blockw<strong>in</strong>dow import BlockW<strong>in</strong>dow<br />
labels = ”one two three four five six seven eight n<strong>in</strong>e”.split()<br />
class TestFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, -1, ”StaticBoxSizer Test”)<br />
self.panel = wx.Panel(self)<br />
# make three static boxes with w<strong>in</strong>dows positioned <strong>in</strong>side them<br />
box1 = self.MakeStaticBoxSizer(“Box 1”, labels[0:3])<br />
box2 = self.MakeStaticBoxSizer(“Box 2”, labels[3:6])<br />
box3 = self.MakeStaticBoxSizer(“Box 3”, labels[6:9])<br />
# We can also use a sizer to manage the placement of other<br />
# sizers (and therefore the w<strong>in</strong>dows and sub-sizers that they<br />
# manage as well.)<br />
sizer = wx.BoxSizer(wx.HORIZONTAL)<br />
sizer.Add(box1, 0, wx.ALL, 10)<br />
sizer.Add(box2, 0, wx.ALL, 10)<br />
sizer.Add(box3, 0, wx.ALL, 10)<br />
self.panel.SetSizer(sizer)<br />
sizer.Fit(self)<br />
352 / 565
def MakeStaticBoxSizer(self, boxlabel, itemlabels):<br />
# first the static box<br />
box = wx.StaticBox(self.panel, -1, boxlabel)<br />
# then the sizer<br />
sizer = wx.StaticBoxSizer(box, wx.VERTICAL)<br />
# then add items to it like normal<br />
for label <strong>in</strong> itemlabels:<br />
bw = BlockW<strong>in</strong>dow(self.panel, label=label)<br />
sizer.Add(bw, 0, wx.ALL, 2)<br />
return sizer<br />
app = wx.PySimpleApp()<br />
TestFrame().Show()<br />
app.Ma<strong>in</strong>Loop()<br />
static box sizerwx.StaticBoxSizerwx.StaticBoxSizer<br />
wx.BoxSizer<br />
wx.StaticBoxSizer(box, orient)<br />
orientwx.BoxSizerbox<br />
wx.StaticBoxstatic box sizer<br />
GetStaticBox()sizerwx.StaticBoxsizer<br />
<br />
wx.StaticBox<strong>wxPython</strong><br />
<br />
wx.StaticBox(parent, id, label, pos=wx.DefaultPosition,<br />
size=wx.DefaultSize, style=0, name=”staticBox”)<br />
static box sizerpos, size, style, name<br />
sizerwx.StaticBox<br />
<br />
353 / 565
ox = wx.StaticBox(self.panel, -1, boxlabel)<br />
sizer<br />
<br />
11.4 sizer<br />
sizer<br />
sizer11.16<br />
sizer<br />
11.16<br />
11.11<br />
<br />
11.11 sizer<br />
import wx<br />
class TestFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, -1, ”Real World Test”)<br />
panel = wx.Panel(self)<br />
# First create the controls<br />
topLbl = wx.StaticText(panel, -1, ”Account Information”)#1 <br />
topLbl.SetFont(wx.Font(18, wx.SWISS, wx.NORMAL, wx.BOLD))<br />
354 / 565
nameLbl = wx.StaticText(panel, -1, ”Name:”)<br />
name = wx.TextCtrl(panel, -1, ””);<br />
addrLbl = wx.StaticText(panel, -1, ”Address:”)<br />
addr1 = wx.TextCtrl(panel, -1, ””);<br />
addr2 = wx.TextCtrl(panel, -1, ””);<br />
cstLbl = wx.StaticText(panel, -1, ”City, State, Zip:”)<br />
city = wx.TextCtrl(panel, -1, ””, size=(150,-1));<br />
state = wx.TextCtrl(panel, -1, ””, size=(50,-1));<br />
zip = wx.TextCtrl(panel, -1, ””, size=(70,-1));<br />
phoneLbl = wx.StaticText(panel, -1, ”Phone:”)<br />
phone = wx.TextCtrl(panel, -1, ””);<br />
emailLbl = wx.StaticText(panel, -1, ”Email:”)<br />
email = wx.TextCtrl(panel, -1, ””);<br />
saveBtn = wx.Button(panel, -1, ”Save”)<br />
cancelBtn = wx.Button(panel, -1, ”Cancel”)<br />
# Now do the layout.<br />
# ma<strong>in</strong>Sizer is the top-level one that manages everyth<strong>in</strong>g<br />
#2 sizer<br />
ma<strong>in</strong>Sizer = wx.BoxSizer(wx.VERTICAL)<br />
ma<strong>in</strong>Sizer.Add(topLbl, 0, wx.ALL, 5)<br />
ma<strong>in</strong>Sizer.Add(wx.StaticL<strong>in</strong>e(panel), 0,<br />
wx.EXPAND|wx.TOP|wx.BOTTOM, 5)<br />
# addrSizer is a grid that holds all of the address <strong>in</strong>fo<br />
#3 <br />
addrSizer = wx.FlexGridSizer(cols=2, hgap=5, vgap=5)<br />
addrSizer.AddGrowableCol(1)<br />
addrSizer.Add(nameLbl, 0,<br />
wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)<br />
addrSizer.Add(name, 0, wx.EXPAND)<br />
addrSizer.Add(addrLbl, 0,<br />
wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)<br />
355 / 565
addrSizer.Add(addr1, 0, wx.EXPAND)<br />
#4 <br />
addrSizer.Add((10,10)) # some empty space<br />
addrSizer.Add(addr2, 0, wx.EXPAND)<br />
addrSizer.Add(cstLbl, 0,<br />
wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)<br />
# the city, state, zip fields are <strong>in</strong> a sub-sizer<br />
#5 <br />
cstSizer = wx.BoxSizer(wx.HORIZONTAL)<br />
cstSizer.Add(city, 1)<br />
cstSizer.Add(state, 0, wx.LEFT|wx.RIGHT, 5)<br />
cstSizer.Add(zip)<br />
addrSizer.Add(cstSizer, 0, wx.EXPAND)<br />
#6 <br />
addrSizer.Add(phoneLbl, 0,<br />
wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)<br />
addrSizer.Add(phone, 0, wx.EXPAND)<br />
addrSizer.Add(emailLbl, 0,<br />
wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)<br />
addrSizer.Add(email, 0, wx.EXPAND)<br />
# now add the addrSizer to the ma<strong>in</strong>Sizer<br />
#7 Flex sizer<br />
ma<strong>in</strong>Sizer.Add(addrSizer, 0, wx.EXPAND|wx.ALL, 10)<br />
# The buttons sizer will put them <strong>in</strong> a row with resizeable<br />
# gaps between and on either side of the buttons<br />
#8 <br />
btnSizer = wx.BoxSizer(wx.HORIZONTAL)<br />
btnSizer.Add((20,20), 1)<br />
btnSizer.Add(saveBtn)<br />
btnSizer.Add((20,20), 1)<br />
btnSizer.Add(cancelBtn)<br />
btnSizer.Add((20,20), 1)<br />
ma<strong>in</strong>Sizer.Add(btnSizer, 0, wx.EXPAND|wx.BOTTOM, 10)<br />
panel.SetSizer(ma<strong>in</strong>Sizer)<br />
356 / 565
# Fit the frame to the needs of the sizer. The frame will<br />
# automatically resize the panel as needed. Also prevent the<br />
# frame from gett<strong>in</strong>g smaller than this size.<br />
ma<strong>in</strong>Sizer.Fit(self)<br />
ma<strong>in</strong>Sizer.SetSizeH<strong>in</strong>ts(self)<br />
app = wx.PySimpleApp()<br />
TestFrame().Show()<br />
app.Ma<strong>in</strong>Loop()<br />
#1 <br />
sizer<br />
#2 sizerma<strong>in</strong>Sizerbox sizer<br />
ma<strong>in</strong>Sizerstatic l<strong>in</strong>e<br />
#3 box sizeraddrSizerflex grid sizer<br />
addrSizer<br />
<br />
gridnameLbl, name, addrLbl, addr1<br />
flex grid<br />
#4 (10,10)<br />
addr2<br />
#5 “City, State, Zip”<br />
box sizercstSizer<br />
cstSizerbox sizeraddrSizer<br />
#6 flex sizer<br />
#7 flex sizersizer<br />
#8 box sizer<br />
sizerma<strong>in</strong>Sizer.Fit(self)<br />
ma<strong>in</strong>Sizer.SetSizeH<strong>in</strong>ts(self)<br />
357 / 565
sizerbox sizer<br />
0<br />
sizerbox sizer<br />
wx.EXPAND<br />
static l<strong>in</strong>esizerflex grid sizer1<br />
“City, State, Zip” <br />
1citystateZIP<br />
0<br />
1<br />
11.17<br />
11.17<br />
11.5 <br />
1Sizer<strong>wxPython</strong><br />
sizersizer<br />
358 / 565
sizer<br />
<br />
2<strong>wxPython</strong>sizerwx.Sizer<br />
sizer<br />
sizersizerFit()<br />
sizer<br />
3sizersizer<br />
sizer<br />
<br />
4<strong>wxPython</strong>sizergrid sizer(wx.GridSizer)<br />
grid sizersizer<br />
sizer<br />
<br />
5sizersizer<br />
sizer<br />
<br />
sizersizer<br />
sizer<br />
359 / 565
12 <br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<strong>wxPython</strong><br />
<strong>wxPython</strong><br />
<strong>wxPython</strong><br />
<strong>wxPython</strong><br />
<br />
<strong>wxPython</strong>device context<br />
API<br />
<br />
12.1 <br />
<br />
<br />
<br />
<strong>wxPython</strong><br />
<br />
<strong>wxPython</strong><br />
(large-scale images)<br />
<br />
360 / 565
12.1.1 <br />
<strong>wxPython</strong><br />
wx.Imagewx.Bitmap<br />
wx.Imagewx.Bitmap<br />
12.1<br />
wx.Image<br />
wx.Image(name, type=wx.BITMAP_TYPE_ANY, <strong>in</strong>dex=-1)<br />
12.1<br />
nametypetypeID<br />
wx.BITMAP_TYPE_ANY12.1<br />
wx.BITMAP_TYPE_ANY<strong>wxPython</strong><br />
<strong>wxPython</strong><br />
12.1wx.BITMAP_TYPE_ANY<br />
12.1 <br />
import wx<br />
filenames = [“image.bmp”, ”image.gif”, ”image.jpg”, ”image.png” ]<br />
class TestFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
361 / 565
wx.Frame.__<strong>in</strong>it__(self, None, title=”Load<strong>in</strong>g Images”)<br />
p = wx.Panel(self)<br />
fgs = wx.FlexGridSizer(cols=2, hgap=10, vgap=10)<br />
for name <strong>in</strong> filenames:<br />
#1 <br />
img1 = wx.Image(name, wx.BITMAP_TYPE_ANY)<br />
# Scale the orig<strong>in</strong>al to another wx.Image<br />
w = img1.GetWidth()<br />
h = img1.GetHeight()<br />
img2 = img1.Scale(w/2, h/2)#2 <br />
#3 <br />
sb1 = wx.StaticBitmap(p, -1, wx.BitmapFromImage(img1))<br />
sb2 = wx.StaticBitmap(p, -1, wx.BitmapFromImage(img2))<br />
# and put them <strong>in</strong>to the sizer<br />
fgs.Add(sb1)<br />
fgs.Add(sb2)<br />
p.SetSizerAndFit(fgs)<br />
self.Fit()<br />
app = wx.PySimpleApp()<br />
frm = TestFrame()<br />
frm.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
<br />
wx.BITMAP_TYPE_ANY<strong>wxPython</strong><br />
<br />
<br />
<strong>wxPython</strong><br />
<br />
362 / 565
wx.ImageHandler<br />
<br />
<br />
<strong>wxPython</strong>12.1<br />
<br />
12.1 <strong>wxPython</strong><br />
wx.ANIHandler<br />
wx.BITMAP_TYPE_ANI<br />
<br />
wx.BMPHandler wx.BITMAP_TYPE_BMP<br />
W<strong>in</strong>dowsOS/2<br />
wx.CURHandle wx.BITMAP_TYPE_CUR<br />
W<strong>in</strong>dows <br />
wx.GIFHandler wx.BITMAP_TYPE_GIF<br />
<br />
wx.ICOHandler wx.BITMAP_TYPE_ICO<br />
W<strong>in</strong>dows<br />
wx.IFFHandler wx.BITMAP_TYPE_IFF<br />
<br />
wx.JPEGHandler wx.BITMAP_TYPE_JPEG<br />
<br />
wx.PCXHandler wx.BITMAP_TYPE_PCX<br />
PC<strong>wxPython</strong><br />
8256<br />
24<br />
363 / 565
wx.PNGHandler wx.BITMAP_TYPE_PNG<br />
<br />
wx.PNMHandler wx.BITMAP_TYPE_PNM<br />
ASCIIRGBRGB<br />
wx.TIFFHandler wx.BITMAP_TYPE_TIF<br />
<br />
wx.XPMHandler wx.BITMAP_TYPE_XPM<br />
XPixMap<br />
wx.BITMAP_TYPE_ANY<br />
<br />
MIMEID<br />
wx.ImageFromMime(name, mimetype, <strong>in</strong>dex=-1)name<br />
mimetype<strong>in</strong>dex<br />
GIF, ICO, TIFF<br />
-1GIFTIFF<br />
<strong>in</strong>dex=0ICO<br />
<br />
<strong>wxPython</strong>wx.Image<br />
wx.EmptyImage(width,height)——<br />
Python<br />
<br />
wx.ImageFromStream(stream,type=wx.BITMAP_TYPE_ANY, <strong>in</strong>dex=-1)<br />
RGB<br />
wx.ImageFromData(width,height,data)data<br />
width*height*3<br />
<br />
wx.Bitmap<br />
wx.Bitmap(name, type=wx.BITMAP_TYPE_ANY)name<br />
type12.1bitmap<br />
364 / 565
wx.Image<br />
wx.Bitmap<br />
wx.EmptyBitmap(width,height,depth=-1)<br />
——widthheightdepth<br />
<br />
wx.BitmapFromBits(bits, width, height, depth=-1)bits<br />
Pythonbits1<br />
0W<strong>in</strong>dows<br />
W<strong>in</strong>dowsAPICreateBitmap()<br />
wxBitmapFromXPMData(listOfStr<strong>in</strong>gs)Python<br />
XPM<br />
wx.Bitmapwx.BitmapFromImage(image, depth=-1)<br />
imagewx.Imagedepth<br />
<br />
wx.ImageFromBitmap(bitmap)<br />
wx.Bitmap12.1<br />
wx.StaticBitmap<br />
<strong>wxPython</strong><br />
12.1.2 <br />
<strong>wxPython</strong><br />
<br />
GetWidth()GetHeight()<br />
GetRed(x, y), GetGreen(x, y), GetBlue(x, y)<br />
0~255C<br />
Python<br />
SetRGB(x, y, red, green, blue)xy<br />
0~255<br />
GetData()GetData()<br />
RGB<br />
0~255<br />
(0,0)(0,0)<br />
(0,0)(0,1)<br />
Python<br />
365 / 565
def GetData(self):<br />
result = ””<br />
for y <strong>in</strong> range(self.GetHeight()):<br />
for x <strong>in</strong> range(self.GetWidth()):<br />
result.append(chr(self.GetRed(x,y)))<br />
result.append(chr(self.GetGreen(x,y)))<br />
result.append(chr(self.GetBlue(x,y)))<br />
return result<br />
SetData(data)RGB<br />
SetData(data)<br />
<br />
C++<br />
GetData()SetData()——<br />
<br />
Python<br />
<br />
<br />
import array<br />
img = wx.EmptyImage(100,100)<br />
a = array.array(‘B’, img.GetData())<br />
for i <strong>in</strong> range(len(a)):<br />
a[i] = (25+i) % 256<br />
img.SetData(a.tostr<strong>in</strong>g())<br />
12.2wx.Image<br />
<br />
<br />
12.2 wx.Image<br />
ConvertToMono(r, g, b)wx.Image<br />
(r, g, b)<br />
Mirror(horizontally=True)horizontally<br />
True<br />
366 / 565
Replace(r1, g1, b1, r2, g2, b2)r1, g1, b1<br />
r2, g2, b2<br />
Rescale(width, height)<br />
<br />
Rotate(angle, rotationCentre, <strong>in</strong>terpolat<strong>in</strong>g=True, offestAfterRotation=None)<br />
angle<br />
rotationCentrewx.Po<strong>in</strong>t<strong>in</strong>terpolat<strong>in</strong>gTrue<br />
offsetAfterRotation<br />
<br />
mask color<br />
Rotate90(clockwise=True)clockwise<br />
90<br />
Scale(width, height)<br />
<br />
<br />
SetMaskColor(red, green, blue)<br />
red, green, blue<br />
SetMask(False)SetMask(True)HasMask()<br />
<br />
SetMaskFromImage(mask, mr, mg, mb)——<br />
wx.Imagemr, mg, mb<br />
<br />
<br />
GetMaskRed()GetMaskGreen(), GetMaskBlue()<br />
wx.Bitmapwx.Mask<br />
<br />
<br />
alpha<br />
alpha0255<br />
SetAlphaData(data)alpha<br />
SetData()<br />
SetData()SetAlphaData()HasAlpha()<br />
alphaGetAlphaData()<br />
367 / 565
SetAlpha(x, y, alpha)alpha<br />
GetAlpha(x, y)<br />
wx.Imagewx.Bitmap<br />
wx.Bitmap<br />
12.1.3 <br />
<br />
<br />
<br />
I<br />
<br />
<br />
<strong>wxPython</strong><br />
<br />
<br />
<strong>wxPython</strong><br />
<br />
<strong>wxPython</strong><br />
wx.Cursor<br />
wx.StockCursor(id)12.3<br />
IDid<br />
12.3 <br />
wx.CURSOR_ARROW<br />
wx.CURSOR_ARROWWAIT<br />
W<strong>in</strong>dows<br />
wx.CURSOR_BLANK<br />
wx.CURSOR_BULLSEYEbullseye cursor<br />
<br />
wx.CURSOR_CHAR<br />
wx.CURSOR_CROSS<br />
368 / 565
wx.CURSOR_HAND<br />
wx.CURSOR_IBEAMI<br />
wx.CURSOR_LEFT_BUTTON——<br />
<br />
wx.CURSOR_MAGNIFIER<br />
wx.CURSOR_MIDDLE_BUTTON<br />
wx.CURSOR_NO_ENTRY<br />
<br />
wx.CURSOR_PAINT_BRUSH<br />
wx.CURSOR_PENCIL<br />
wx.CURSOR_POINT_LEFT<br />
wx.CURSOR_POINT_RIGHT<br />
wx.CURSOR_QUESTION_ARROW<br />
<br />
wx.CURSOR_RIGHT_ARROW<br />
<br />
wx.CURSOR_RIGHT_BUTTON<br />
wx.CURSOR_SIZENESW<br />
45<br />
wx.CURSOR_SIZENS<br />
wx.CURSOR_SIZENWSE<br />
135<br />
wx.CURSOR_SIZEWE<br />
wx.CURSOR_SIZING<br />
wx.CURSOR_SPRAYCAN<br />
wx.CURSOR_WAIT<br />
369 / 565
wx.CURSOR_WATCH<br />
<br />
<br />
<br />
wx.CursorFromImage(image)<br />
imagewx.Image<br />
32*32MacOS16*16<br />
(0,0)<br />
<br />
image.SetOptionInt(wx.IMAGE_OPTION_CUR_HOTSPOT_X, 0)<br />
image.SetOptionInt(wx.IMAGE_OPTION_CUR_HOTSPOT_Y, 22)<br />
wx.Cursor<br />
wx.Cursor(name, type, hotSpotX=0, hotSpotY=0)<br />
nametype<br />
wx.Imagewx.Bitmapwx.BITMAP_TYPE_hotSpotX<br />
hotSpotYwx.BITMAP_TYPE_CUR<br />
.cur.cur<br />
<strong>wxPython</strong><br />
SetCursor(cursor)<br />
wx.SetCurso(cursor)<br />
<br />
<br />
<br />
12.2 <br />
UI<br />
<strong>wxPython</strong><br />
UI<br />
6<br />
370 / 565
<strong>wxPython</strong><br />
<br />
<strong>wxPython</strong><br />
<br />
wx.DCwx.DCAPIAPI<br />
6<br />
<br />
<br />
12.2.1 <br />
<strong>wxPython</strong>wx.DC<br />
* <br />
* <br />
* <br />
<br />
<br />
<strong>wxPython</strong><br />
<br />
wx.ClientDC<br />
wx.Pa<strong>in</strong>tDC<br />
wx.W<strong>in</strong>dowDC<br />
wx.ScreenDC<br />
<br />
<br />
——<br />
<br />
371 / 565
wx.ClientDCwx.Pa<strong>in</strong>tDC<br />
EVT_PAINT<br />
wx.Pa<strong>in</strong>tDC<br />
wx.ClientDCEVT_PAINT<br />
wx.Pa<strong>in</strong>tDC<br />
wx.Pa<strong>in</strong>tDC<br />
pa<strong>in</strong>t)wx.Pa<strong>in</strong>tDC<br />
<br />
client<br />
pa<strong>in</strong>t)<strong>wxPython</strong><br />
wx.ClientDC(w<strong>in</strong>dow)wx.Pa<strong>in</strong>tDC(w<strong>in</strong>dow)<br />
<br />
<br />
<br />
wx.W<strong>in</strong>dowDCwx.W<strong>in</strong>dowDCwx.ClientDC<br />
wx.W<strong>in</strong>dowDC(w<strong>in</strong>dow)wx.ClientDC<br />
pa<strong>in</strong>twx.W<strong>in</strong>dowDC——<br />
pa<strong>in</strong>t<br />
<br />
wx.ScreenDC<br />
pa<strong>in</strong>t)<br />
——wx.ScreenDC()wx.ScreenDC<br />
<br />
<br />
<br />
<br />
<br />
wx.MemoryDC<br />
wx.MetafileDC<br />
wx.PostScriptDC<br />
372 / 565
wx.Pr<strong>in</strong>terDC<br />
wx.MemoryDC<br />
wx.MemoryDC()<br />
wx.MemoryDC<br />
wx.BitmapSelectObject(bitmap)<br />
<br />
Blit()<br />
<br />
W<strong>in</strong>dowsmetafilewx.MetafileDC<br />
W<strong>in</strong>dows<br />
wx.MetafileDC(filename=””)filename<br />
<br />
Close()<br />
<strong>wxPython</strong>wx.Metafile<strong>wxPython</strong><br />
wx.MetafileSetClipboard(width=0,height=0)<br />
<br />
wx.PostScriptDC<br />
Encapsulated PostScript files.eps<br />
wx.PostScriptDC——wx.PostScriptDC(pr<strong>in</strong>tData)pr<strong>in</strong>tData<br />
wx.Pr<strong>in</strong>tData17PostScript<br />
wx.Pr<strong>in</strong>tData<br />
.eps<br />
data = wx.Pr<strong>in</strong>tData()<br />
data.SetFileName(“/tmp/test.eps”)<br />
data.SetPaperId(wx.PAPER_LETTER)<br />
dc = wx.PostScriptDC(data)<br />
dc.StartDoc(“”)<br />
dc.DrawCircle(300,300, 100)<br />
dc.EndDoc() # the file is written at this po<strong>in</strong>t<br />
W<strong>in</strong>dowswx.Pr<strong>in</strong>terDCW<strong>in</strong>dows<br />
——<br />
wx.Pr<strong>in</strong>terDC(pr<strong>in</strong>tData)17<br />
373 / 565
wx.BufferedDC<br />
wx.BufferedPa<strong>in</strong>tDC<br />
<br />
<br />
<br />
<strong>wxPython</strong>——wx.BufferedDC<br />
wx.ClientDCwx.BufferedPa<strong>in</strong>tDC<br />
wx.Pa<strong>in</strong>tDC<br />
wxBufferedDC<br />
——<br />
wx.BufferedDC(dc, buffer=None)wx.BufferedPa<strong>in</strong>tDC<br />
——wx.BufferedPa<strong>in</strong>tDC(dc, buffer=None)dc<br />
wx.BufferedPa<strong>in</strong>tDC<br />
wx.Pa<strong>in</strong>tDCbuffer<br />
buffer<br />
<br />
<br />
<br />
C++<br />
Blit()<br />
<br />
12.2.2 <br />
<br />
<br />
——<br />
<strong>wxPython</strong>API<br />
12.4<br />
<br />
374 / 565
12.4 <br />
CrossHair(x, y)——y<br />
x(x,y)<br />
DrawArc(x1, y1, x2, y2, xc, yc)(x1,y1)(x2,y2)<br />
(xc,yc)<br />
<br />
DrawCheckMark(x, y, width, height)<br />
(x,y)widthheight<br />
<br />
DrawCircle(x, y, radius)radius(x,y)<br />
DrawEllipse(x, y, width, height)<br />
(x,y)widthheight<br />
DrawEllipticArc(x, y, width, height, start, end)<br />
DrawEllipsestartend<br />
360start<br />
end<br />
DrawL<strong>in</strong>e(x1, y1, x2, y2(x1,y1)(x2,y2)<br />
<br />
DrawL<strong>in</strong>es(po<strong>in</strong>ts, xoffset=0, yoffset=0)po<strong>in</strong>tswx.Po<strong>in</strong>t<br />
wx.Po<strong>in</strong>tpo<strong>in</strong>t<br />
po<strong>in</strong>toffsetoffset<br />
<br />
DrawPolygon(po<strong>in</strong>ts, xoffset=0, yoffset=0fillstyle=wx.ODDEVEN_RULE)<br />
DrawL<strong>in</strong>es<br />
<br />
DrawPo<strong>in</strong>t(x, y)<br />
DrawRectangle(x, y, width, height)(x,y)<br />
widthheight<br />
DrawRoundedRectangle(x, y, width, height, radius=20)DrawRectangle()<br />
90radiusradius<br />
375 / 565
adius<br />
radius * dimension<br />
DrawSpl<strong>in</strong>e(po<strong>in</strong>ts)spl<strong>in</strong>e<br />
FloodFill(x, y, color, style=wx.FLOOD_SURFACE)<br />
(x,y)stylewx.FLOOD_SURFACE<br />
stylewx.FLOOD_BORDER<br />
<br />
xyDrawDraw...Po<strong>in</strong>t<br />
Draw...Po<strong>in</strong>twx.Po<strong>in</strong>t(x,y)<br />
DrawCirclePo<strong>in</strong>t(pt, radius)x,ywidth,height<br />
Draw...Po<strong>in</strong>tSizewx.Po<strong>in</strong>twx.Size<br />
DrawRectanglePo<strong>in</strong>tSize(pt, sz)Draw...Rect<br />
wx.RectDrawRectangleRect(rect)<br />
GetSize()wx.Size<br />
GetPixel(x, y)<br />
wx.Color<br />
12.2<br />
12.2draw<br />
376 / 565
12.20-100<br />
<br />
<br />
<br />
12.2 <br />
import wx<br />
import math<br />
import random<br />
class RadarGraph(wx.W<strong>in</strong>dow):<br />
”””<br />
A simple radar graph that plots a collection of values <strong>in</strong> the<br />
range of 0-100 onto a polar coord<strong>in</strong>ate system designed to easily<br />
show outliers, etc. You might use this k<strong>in</strong>d of graph to monitor<br />
some sort of resource allocation metrics, and a quick glance at<br />
the graph can tell you when conditions are good (with<strong>in</strong> some<br />
accepted tolerance level) or approach<strong>in</strong>g critical levels (total<br />
resource consumption).<br />
”””<br />
def __<strong>in</strong>it__(self, parent, title, labels):<br />
wx.W<strong>in</strong>dow.__<strong>in</strong>it__(self, parent)<br />
self.title = title<br />
self.labels = labels<br />
self.data = [0.0] * len(labels)<br />
self.titleFont = wx.Font(14, wx.SWISS, wx.NORMAL, wx.BOLD)<br />
self.labelFont = wx.Font(10, wx.SWISS, wx.NORMAL, wx.NORMAL)<br />
self.InitBuffer()<br />
self.B<strong>in</strong>d(wx.EVT_SIZE, self.OnSize)<br />
self.B<strong>in</strong>d(wx.EVT_PAINT, self.OnPa<strong>in</strong>t)<br />
def OnSize(self, evt):<br />
# When the w<strong>in</strong>dow size changes we need a new buffer.<br />
self.InitBuffer()<br />
377 / 565
def OnPa<strong>in</strong>t(self, evt):<br />
# This automatically Blits self.buffer to a wx.Pa<strong>in</strong>tDC when<br />
# the dc is destroyed, and so noth<strong>in</strong>g else needs done.<br />
dc = wx.BufferedPa<strong>in</strong>tDC(self, self.buffer)#1 <br />
def InitBuffer(self):#2 <br />
# Create the buffer bitmap to be the same size as the w<strong>in</strong>dow,<br />
# then draw our graph to it. S<strong>in</strong>ce we use wx.BufferedDC<br />
# whatever is drawn to the buffer is also drawn to the w<strong>in</strong>dow.<br />
w, h = self.GetClientSize()<br />
self.buffer = wx.EmptyBitmap(w, h)<br />
dc = wx.BufferedDC(wx.ClientDC(self), self.buffer)<br />
self.DrawGraph(dc)<br />
def GetData(self):<br />
return self.data<br />
def SetData(self, newData):<br />
assert len(newData) == len(self.data)<br />
self.data = newData[:]<br />
# , <br />
dc = wx.BufferedDC(wx.ClientDC(self), self.buffer)<br />
self.DrawGraph(dc)<br />
def PolarToCartesian(self, radius, angle, cx, cy):<br />
x = radius * math.cos(math.radians(angle))<br />
y = radius * math.s<strong>in</strong>(math.radians(angle))<br />
return (cx+x, cy-y)<br />
def DrawGraph(self, dc):#<br />
spacer = 10<br />
scaledmax = 150.0<br />
dc.SetBackground(wx.Brush(self.GetBackgroundColour()))<br />
378 / 565
dc.Clear()<br />
dw, dh = dc.GetSize()<br />
# F<strong>in</strong>d out where to draw the title and do it<br />
dc.SetFont(self.titleFont)<br />
tw, th = dc.GetTextExtent(self.title)<br />
dc.DrawText(self.title, (dw-tw)/2, spacer)# <br />
# f<strong>in</strong>d the center of the space below the title<br />
# <br />
th = th + 2*spacer<br />
cx = dw/2<br />
cy = (dh-th)/2 + th<br />
# calculate a scale factor to use for draw<strong>in</strong>g the graph based<br />
# on the m<strong>in</strong>imum available width or height<br />
# <br />
m<strong>in</strong>dim = m<strong>in</strong>(cx, (dh-th)/2)<br />
scale = m<strong>in</strong>dim/scaledmax<br />
# draw the graph axis and ”bulls-eye” with r<strong>in</strong>gs at scaled 25,<br />
# 50, 75 and 100 positions<br />
# <br />
dc.SetPen(wx.Pen(“black”, 1))<br />
dc.SetBrush(wx.TRANSPARENT_BRUSH)<br />
dc.DrawCircle(cx,cy, 25*scale)<br />
dc.DrawCircle(cx,cy, 50*scale)<br />
dc.DrawCircle(cx,cy, 75*scale)<br />
dc.DrawCircle(cx,cy, 100*scale)<br />
dc.SetPen(wx.Pen(“black”, 2))<br />
dc.DrawL<strong>in</strong>e(cx-110*scale, cy, cx+110*scale, cy)<br />
dc.DrawL<strong>in</strong>e(cx, cy-110*scale, cx, cy+110*scale)<br />
# Now f<strong>in</strong>d the coord<strong>in</strong>ates for each data po<strong>in</strong>t, draw the<br />
# labels, and f<strong>in</strong>d the max data po<strong>in</strong>t<br />
dc.SetFont(self.labelFont)<br />
maxval = 0<br />
angle = 0<br />
polypo<strong>in</strong>ts = []<br />
379 / 565
for i, label <strong>in</strong> enumerate(self.labels):<br />
val = self.data[i]<br />
po<strong>in</strong>t = self.PolarToCartesian(val*scale, angle, cx, cy)# <br />
polypo<strong>in</strong>ts.append(po<strong>in</strong>t)<br />
x, y = self.PolarToCartesian(125*scale, angle, cx,cy)<br />
dc.DrawText(label, x, y)# <br />
if val > maxval:<br />
maxval = val<br />
angle = angle + 360/len(self.labels)<br />
# Set the brush color based on the max value (green is good,<br />
# red is bad)<br />
c = ”forest green”<br />
if maxval > 70:<br />
c = ”yellow”<br />
if maxval > 95:<br />
c = ”red”<br />
# F<strong>in</strong>ally, draw the plot data as a filled polygon<br />
dc.SetBrush(wx.Brush(c))# <br />
dc.SetPen(wx.Pen(“navy”, 3))<br />
dc.DrawPolygon(polypo<strong>in</strong>ts) #<br />
class TestFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, title=”Double Buffered Draw<strong>in</strong>g”,<br />
size=(480,480))<br />
self.plot = RadarGraph(self, ”Sample ’Radar’ Plot”,<br />
[“A”, ”B”, ”C”, ”D”, ”E”, ”F”, ”G”, ”H”])<br />
# Set some random <strong>in</strong>itial data values<br />
data = []<br />
for d <strong>in</strong> self.plot.GetData():<br />
data.append(random.rand<strong>in</strong>t(0, 75))<br />
self.plot.SetData(data)<br />
# Create a timer to update the data values<br />
380 / 565
self.B<strong>in</strong>d(wx.EVT_TIMER, self.OnTimeout)<br />
self.timer = wx.Timer(self)<br />
self.timer.Start(500)<br />
def OnTimeout(self, evt):<br />
# simulate the positive or negative growth of each data value<br />
data = []<br />
for d <strong>in</strong> self.plot.GetData():<br />
val = d + random.uniform(-5, 5)<br />
if val < 0:<br />
val = 0<br />
if val > 110:<br />
val = 110<br />
data.append(val)<br />
self.plot.SetData(data)<br />
app = wx.PySimpleApp()<br />
frm = TestFrame()<br />
frm.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
#1 wx.BufferedPa<strong>in</strong>tDC<br />
OnPa<strong>in</strong>tself.buffer<br />
wx.Pa<strong>in</strong>tDC<br />
#2 <br />
wx.BufferedDCInitBuffer<br />
<br />
12.2.3 <br />
imagebitmap<br />
blit<br />
<br />
blit<br />
<br />
<br />
381 / 565
* Blit()<br />
* DrawBitmap()<br />
* DrawIcon()<br />
Blit()<br />
Blit(xdest, ydest, width, height, source, xsrc, ysrc,<br />
logicalFunc=wx.COPY, useMask=False, xsrcMask=-1,<br />
ysrcMask=-1)<br />
<br />
Blit()<br />
<br />
Blit()<br />
Blit()<br />
xdest, ydest, width, height<br />
xsrc, ysrcwx.DC<br />
wx.DCwx.DC<br />
logicalFunc——<br />
12.6<br />
useMaskTrueblit<br />
alpha<br />
xsrcMask ysrcMask<br />
xsrcMask ysrcMaskxsrc, ysrc<br />
blitBlitPo<strong>in</strong>tSize()wx.Po<strong>in</strong>tblit<br />
wx.Sizewidthheight<br />
<br />
<br />
<br />
DrawBitmap(bitmap,x, y, useMask=False)bitmapwx.Bitmap<br />
(x,y)useMask<br />
FalseTrue<br />
alpha<br />
382 / 565
12.3<br />
12.3<br />
12.3<br />
12.3<br />
12.3 <br />
# This one shows how to draw images on a DC.<br />
import wx<br />
import random<br />
random.seed()<br />
class RandomImagePlacementW<strong>in</strong>dow(wx.W<strong>in</strong>dow):<br />
def __<strong>in</strong>it__(self, parent, image):<br />
wx.W<strong>in</strong>dow.__<strong>in</strong>it__(self, parent)<br />
self.photo = image.ConvertToBitmap()# <br />
# choose some random positions to draw the image at:<br />
# <br />
self.positions = [(10,10)]<br />
383 / 565
for x <strong>in</strong> range(50):<br />
x = random.rand<strong>in</strong>t(0, 1000)<br />
y = random.rand<strong>in</strong>t(0, 1000)<br />
self.positions.append( (x,y) )<br />
# B<strong>in</strong>d the Pa<strong>in</strong>t event<br />
self.B<strong>in</strong>d(wx.EVT_PAINT, self.OnPa<strong>in</strong>t)<br />
def OnPa<strong>in</strong>t(self, evt):<br />
# create and clear the DC<br />
dc = wx.Pa<strong>in</strong>tDC(self)<br />
brush = wx.Brush(“sky blue”)<br />
dc.SetBackground(brush)<br />
dc.Clear()# <br />
# draw the image <strong>in</strong> random locations<br />
for x,y <strong>in</strong> self.positions:# <br />
dc.DrawBitmap(self.photo, x, y, True)<br />
class TestFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, title=”Load<strong>in</strong>g Images”,<br />
size=(640,480))<br />
img = wx.Image(“masked-portrait.png”)<br />
w<strong>in</strong> = RandomImagePlacementW<strong>in</strong>dow(self, img)<br />
app = wx.PySimpleApp()<br />
frm = TestFrame()<br />
frm.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
DrawIcon(icon, x, y)wx.Icon<br />
(x,y)wx.Icon<br />
wx.Bitmapwx.Icon<br />
384 / 565
12.2.4 <br />
DrawText(text, x, y)<br />
textxy<br />
DrawRotatedText(text, x, y, angle)angle<br />
DrawTextPo<strong>in</strong>t(text, pt)<br />
DrawRotatedTextPo<strong>in</strong>t(text, pt, angle)<br />
<br />
get*set*<br />
<br />
GetTextForeground(), SetTextForegroud(color), GetTextBackground(), SetTextBackg<br />
round(color), GetFont(), and SetFont(font)<strong>wxPython</strong><br />
SetBackgroundMode(mode)<br />
modewx.SOLID<br />
modewx.TRANSPARENT<br />
<br />
GetCharHeight()GetCharWidth()<br />
<br />
GetTextExtent(str<strong>in</strong>g)<br />
(width,height)<br />
<br />
GetFullTextExtent(str<strong>in</strong>g)<br />
(width,height,descent,externalLead<strong>in</strong>g)descent<br />
externalLead<strong>in</strong>g<br />
0<br />
GetPartialTextExtents(text)<br />
<br />
<br />
widths,<br />
<br />
widths[i] = GetTextExtent(text[:i])[0]<br />
<br />
<br />
<br />
385 / 565
12.3 <br />
<br />
<br />
<br />
12.3.1 <br />
<br />
wx.Pen<br />
GetPen()SetPen(pen)<br />
wx.Pen<br />
<br />
wx.Pen(colour, width=1, style=wx.SOLID)<br />
colourwx.ColourRGB<br />
RGB“#12C588”width<br />
style12.5<br />
style——<br />
12.5 wx.Pen <br />
wx.BDIAGONAL_HATCH<br />
wx.CROSSDIAG_HATCH wx.BDIAGONAL_HATCHwx.FDIAGONAL_HATCH<br />
X<br />
wx.CROSS_HATCH+<br />
wx.DOT<br />
wx.DOT_DASH<br />
wx.FDIAGONAL_HATCH<br />
wx.HORIZONTAL_HATCH<br />
wx.LONG_DASH<br />
386 / 565
wx.SHORT_DASH<br />
wx.SOLID<br />
wx.STIPPLE<br />
wx.TRANSPARENT<br />
wx.USER_DASH<br />
wx.VERTICAL_HATCH<br />
<br />
——<br />
<br />
wx.BLACK_DASHED_PEN<br />
wx.BLACK_PEN<br />
wx.CYAN_PEN<br />
wx.GREEN_PEN<br />
wx.GREY_PEN<br />
wx.LIGHT_GREY_PEN<br />
wx.MEDIUM_GREY_PEN<br />
wx.RED_PEN<br />
wx.TRANSPARENT_PEN<br />
wx.WHITE_PEN<br />
——<br />
GetColour(), SetColour(color), GetWidth(), SetWidth(width), GetStyle(), <br />
SetStyle()<br />
“end cap”<br />
GetCap()SetCap(cap)cap<br />
wx.CAP_BUTT<br />
wx.CAP_PROJECTING<br />
wx.CAP_ROUND<br />
<br />
wx.GetJo<strong>in</strong>(), wx.SetJo<strong>in</strong>(jo<strong>in</strong>)jo<strong>in</strong><br />
wx.JOIN_BEVEL<br />
387 / 565
wx.JOIN_MITER<br />
wx.JOIN_ROUND<br />
wx.USER_DASHGetDashes()<br />
SetDashes(dashes)dashes<br />
wx.STIPPLESetStipple(stipple)<br />
GetStipple()<br />
blit<br />
<br />
SetLogicalFunction(function)functionwx.COPY<br />
<br />
wx.XORwx.INVERTrubberband<strong>in</strong>g12.3<br />
<br />
Python<br />
&<br />
|<br />
^<br />
~<br />
12.6 <br />
wx.AND&<br />
wx.AND_INVERT~ & <br />
wx.AND_REVERSE & ~<br />
wx.CLEAR0——<br />
wx.COPY<br />
wx.EQUIV~ ^ <br />
wx.INVERT~<br />
wx.NAND~ | ~<br />
388 / 565
wx.NOR~ & ~<br />
wx.NO_OP<br />
wx.OR | <br />
wx.OR_INVERT~ | <br />
wx.OR_REVERSE | <br />
wx.SET1——<br />
wx.SRC_INVERT~<br />
wx.XOR ^ <br />
blit<br />
<br />
12.3.2 <br />
<br />
wx.Brush GetBrush()<br />
SetBrush(brush)Clear()<br />
<br />
wx.Brush<br />
wx.Brush(colour, style=wx.SOLID)<br />
colourwx.Colour<br />
RGBstyle<br />
<br />
wx.BDIAGONAL_HATCH<br />
wx.CROSSDIAG_HATCH<br />
wx.CROSS_HATCH<br />
wx.FDIAGONAL_HATCH<br />
wx.HORIZONTAL_HATCH<br />
wx.SOLID<br />
wx.STIPPLE<br />
389 / 565
wx.TRANSPARENT<br />
wx.VERTICAL_HATCH<br />
get*set*——<br />
GetColour(), SetColour(colour), GetStyle(), SetStyle()<br />
SetStipple(bitmap)stipple<br />
stipplewx.STIPPLEGetStipple()<br />
stipple<br />
<br />
<br />
<br />
wx.BrushFromBitmap(Bitmap)<br />
12.3.3 <br />
<strong>wxPython</strong><br />
<strong>wxPython</strong><br />
(0,0)yxy<br />
SetAxisOrientation(xLeftRight,yBottomUp)<br />
xLeftRightTrue<br />
xyBottomUpTrue<br />
y<br />
<br />
SetMapMode(mode)mode<br />
<br />
mode12.7<br />
12.7 <br />
wx.MM_LOMETRIC<br />
0.1<br />
wx.MM_METRIC<br />
1<br />
wx.MM_POINTS<br />
1<br />
390 / 565
wx.MM_TEXT<br />
1()<br />
wx.MM_TWIPS<br />
1/20<br />
<br />
GetPPI()<br />
<br />
<br />
LogicalToDeviceX(x)LogicalToDeviceY(y)<br />
<br />
<br />
LogicalToDeviceXRel(x)LogicalToDeviceYRel(y)<br />
<br />
DeviceToLogicalX(x), DeviceToLogicalY(y), DeviceToLogicalXRel(x), <br />
DeviceToLogcialYRel(y)<br />
<br />
<br />
<br />
“clipp<strong>in</strong>g”<br />
SetClipp<strong>in</strong>gRegion(x, y, width, height)x,ywidth<br />
height<br />
DestroyClipp<strong>in</strong>gRegion()clip<br />
GetClipp<strong>in</strong>gBox()(x, y, width, height)<br />
“bound<strong>in</strong>g box”<br />
“bound<strong>in</strong>g box”<strong>wxPython</strong><br />
<br />
MaxX(), MaxY(), M<strong>in</strong>X(), M<strong>in</strong>Y()<br />
“bound<strong>in</strong>g box”<br />
“bound<strong>in</strong>g box”<br />
CalcBound<strong>in</strong>gBox(x,y)“bound<strong>in</strong>g box”<br />
ResetBound<strong>in</strong>gBox()<br />
391 / 565
“bound<strong>in</strong>g box”“bound<strong>in</strong>g box”<br />
<br />
12.3.4 <br />
<strong>wxPython</strong><br />
aquamar<strong>in</strong>e black blue<br />
blue violet brown cadet blue<br />
coral cornflower blue cyan<br />
dark gray dark green dark olive green<br />
dark orchid dark slate blue dark slate gray<br />
dark turquoise dim gray firebrick<br />
forest green gold goldenrod<br />
gray green green yellow<br />
<strong>in</strong>dian red khaki light blue<br />
light gray light steel blue lime green<br />
magenta maroon medium aquamar<strong>in</strong>e<br />
medium blue medium forest green medium goldenrod <br />
<br />
medium orchid medium sea green medium slate blue<br />
<br />
medium spr<strong>in</strong>g green medium turquoise<br />
medium violet red midnight blue navy<br />
orange<br />
orange red orchid pale green<br />
p<strong>in</strong>k plum purple red<br />
salmon sea green sienna sky blue<br />
slate blue spr<strong>in</strong>g green steel blue tan<br />
thistle turquoise violet violet red<br />
wheat white yellow yellow green<br />
updateColourDB<br />
wx.lib.colourdb<br />
12.4 <br />
1<strong>wxPython</strong><br />
wx.Image<br />
wx.Bitmap<br />
<br />
wx.Image<br />
392 / 565
alpha<br />
<br />
2wx.Image<br />
<br />
3<br />
4wx.DC<br />
APIwx.DC<br />
<br />
<br />
EVT_PAINT<br />
<br />
<br />
5wx.MemoryDCwx.BufferedDC<br />
wx.BufferedDC<br />
wx.BufferedPa<strong>in</strong>tDC<br />
6<br />
wx.Sizewx.Po<strong>in</strong>t<br />
<br />
<br />
7Blit()<br />
<br />
<br />
8wx.Penwx.Pen<br />
wx.Brush<br />
wx.Penwx.Brush<br />
wx.Pen<br />
9<br />
<br />
clipp<strong>in</strong>g<br />
“bound<strong>in</strong>g box”<br />
<br />
393 / 565
<strong>wxPython</strong><br />
<br />
<strong>wxPython</strong><br />
13“”<br />
W<strong>in</strong>dows<br />
<br />
14“grid”grid<br />
grid<br />
15“”<br />
<br />
16“HTML”HTML<br />
HTML<br />
HTML17“<strong>wxPython</strong>”<br />
<strong>wxPython</strong><br />
18<br />
“<strong>wxPython</strong>”<br />
<br />
(timer)<strong>wxPython</strong><br />
<br />
394 / 565
13 <br />
<br />
<br />
<br />
<br />
<br />
<br />
<strong>wxPython</strong><br />
HTML<br />
8<br />
<br />
<br />
<br />
13.1 <br />
<br />
* (icon)<br />
* (small icon)<br />
* (list)<br />
* (report)<br />
W<strong>in</strong>dows(Explorer)MacF<strong>in</strong>der<br />
<br />
<br />
395 / 565
13.1.1 <br />
W<strong>in</strong>dows<br />
<br />
13.1<br />
<br />
13.113.1.png<br />
<br />
13.1 <br />
#-*- encod<strong>in</strong>g:UTF-8 -*-<br />
import wx<br />
import sys, glob<br />
class DemoFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, -1,<br />
”wx.ListCtrl <strong>in</strong> wx.LC_ICON mode”,<br />
size=(600,400))<br />
# load some images <strong>in</strong>to an image list<br />
il = wx.ImageList(32,32, True)#<br />
for name <strong>in</strong> glob.glob(“icon.png”):<br />
bmp = wx.Bitmap(name, wx.BITMAP_TYPE_PNG)<br />
il_max = il.Add(bmp)<br />
# create the list control<br />
#<br />
self.list = wx.ListCtrl(self, -1,<br />
style=wx.LC_ICON | wx.LC_AUTOARRANGE)<br />
# assign the image list to it<br />
self.list.AssignImageList(il, wx.IMAGE_LIST_NORMAL)<br />
# create some items for the list<br />
#<br />
for x <strong>in</strong> range(25):<br />
img = x % (il_max+1)<br />
396 / 565
self.list.InsertImageStr<strong>in</strong>gItem(x,<br />
”This is item %02d” % x, img)<br />
app = wx.PySimpleApp()<br />
frame = DemoFrame()<br />
frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
13.1<br />
13.1DemoFrame“image list”<br />
<br />
“image list”<br />
13.1.2 <br />
13.2<br />
<br />
<br />
<br />
397 / 565
13.2<br />
13.2<br />
import wx<br />
import sys, glob<br />
class DemoFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, -1,<br />
”wx.ListCtrl <strong>in</strong> wx.LC_SMALL_ICON mode”,<br />
size=(600,400))<br />
# load some images <strong>in</strong>to an image list<br />
il = wx.ImageList(16,16, True)<br />
for name <strong>in</strong> glob.glob(“smicon.png”):<br />
bmp = wx.Bitmap(name, wx.BITMAP_TYPE_PNG)<br />
il_max = il.Add(bmp)<br />
# create the list control<br />
self.list = wx.ListCtrl(self, -1,<br />
style=wx.LC_SMALL_ICON<br />
| wx.LC_AUTOARRANGE<br />
)<br />
398 / 565
# assign the image list to it<br />
self.list.AssignImageList(il, wx.IMAGE_LIST_SMALL)<br />
# create some items for the list<br />
for x <strong>in</strong> range(25):<br />
img = x % (il_max+1)<br />
self.list.InsertImageStr<strong>in</strong>gItem(x,<br />
”This is item %02d” % x,<br />
img)<br />
app = wx.PySimpleApp()<br />
frame = DemoFrame()<br />
frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
13.1.3 <br />
<br />
13.3<br />
<br />
<br />
13.3<br />
399 / 565
13.3<br />
import wx<br />
import sys, glob<br />
class DemoFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, -1,<br />
”wx.ListCtrl <strong>in</strong> wx.LC_LIST mode”,<br />
size=(600,400))<br />
# load some images <strong>in</strong>to an image list<br />
il = wx.ImageList(16,16, True)<br />
for name <strong>in</strong> glob.glob(“smicon.png”):<br />
bmp = wx.Bitmap(name, wx.BITMAP_TYPE_PNG)<br />
il_max = il.Add(bmp)<br />
# create the list control<br />
self.list = wx.ListCtrl(self, -1, style=wx.LC_LIST)<br />
# assign the image list to it<br />
self.list.AssignImageList(il, wx.IMAGE_LIST_SMALL)<br />
# create some items for the list<br />
for x <strong>in</strong> range(25):<br />
img = x % (il_max+1)<br />
self.list.InsertImageStr<strong>in</strong>gItem(x,<br />
”This is item %02d” % x,<br />
img)<br />
app = wx.PySimpleApp()<br />
frame = DemoFrame()<br />
frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
400 / 565
13.1.4<br />
<br />
13.4<br />
13.4<br />
13.213.4<br />
13.2 <br />
#!/usr/b<strong>in</strong>/python<br />
#-*- encod<strong>in</strong>g:UTF-8 -*-<br />
import wx<br />
import sys, glob, random<br />
import data<br />
class DemoFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, -1,<br />
”wx.ListCtrl <strong>in</strong> wx.LC_REPORT mode”,<br />
size=(600,400))<br />
il = wx.ImageList(16,16, True)<br />
for name <strong>in</strong> glob.glob(“smicon.png”):<br />
401 / 565
mp = wx.Bitmap(name, wx.BITMAP_TYPE_PNG)<br />
il_max = il.Add(bmp)<br />
self.list = wx.ListCtrl(self, -1, style=wx.LC_REPORT)#<br />
self.list.AssignImageList(il, wx.IMAGE_LIST_SMALL)<br />
# Add some columns<br />
for col, text <strong>in</strong> enumerate(data.columns):#<br />
self.list.InsertColumn(col, text)<br />
# add the rows<br />
for item <strong>in</strong> data.rows:#<br />
<strong>in</strong>dex = self.list.InsertStr<strong>in</strong>gItem(sys.max<strong>in</strong>t, item[0])<br />
for col, text <strong>in</strong> enumerate(item[1:]):<br />
self.list.SetStr<strong>in</strong>gItem(<strong>in</strong>dex, col+1, text)<br />
# give each item a random image<br />
img = random.rand<strong>in</strong>t(0, il_max)<br />
self.list.SetItemImage(<strong>in</strong>dex, img, img)<br />
# set the width of the columns <strong>in</strong> various ways<br />
self.list.SetColumnWidth(0, 120)#<br />
self.list.SetColumnWidth(1, wx.LIST_AUTOSIZE)<br />
self.list.SetColumnWidth(2, wx.LIST_AUTOSIZE)<br />
self.list.SetColumnWidth(3, wx.LIST_AUTOSIZE_USEHEADER)<br />
app = wx.PySimpleApp()<br />
frame = DemoFrame()<br />
frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
#-<br />
*- encod<strong>in</strong>g:UTF-8 -*-<br />
<br />
<br />
<br />
grid14<br />
402 / 565
13.1.5 <br />
<strong>wxPython</strong>wx.ListCtrl<br />
<br />
wx.ListCtrl(parent, id, pos=wx.DefaultPosition,<br />
size=wx.DefaultSize, style=wx.LC_ICON,<br />
validator=wx.DefaultValidator, name=”listCtrl”)<br />
parent<br />
id<strong>wxPython</strong>-1pos<br />
sizestyle——<br />
validator9name<br />
<br />
style<br />
wx.LC_ICON<br />
13.1<br />
13.1 <br />
wx.LC_ICON<br />
wx.LC_LIST<br />
wx.LC_REPORT<br />
wx.LC_SMALL_ICON<br />
<br />
wx.LC_ALIGN_TOP<br />
wx.LC_ALIGN_LEFTLC_AUTOARRANGE<br />
<br />
13.2<br />
13.2 <br />
wx.LC_HRULES<br />
wx.LC_NO_HEADER<br />
403 / 565
wx.LC_VRULES<br />
wx.LC_REPORT|<br />
wx.LC_HRULES|wx.LC_VRULES<br />
<br />
wx.LC_SINGLE_SEL<br />
<br />
SetS<strong>in</strong>gleStyle(style, add=True)<br />
add<br />
listCtrl.SetS<strong>in</strong>gleStyle(LC_HRULES,True)<br />
listCtrl.SetS<strong>in</strong>gleStyle(LC_HRULES,False)listCtrl<br />
SetW<strong>in</strong>dowStyleFlag(style)<br />
SetW<strong>in</strong>dowStyleFlag(LC_REPORT | LC_NO_HEADER)<br />
<br />
13.2 <br />
<strong>wxPython</strong><br />
<br />
<br />
13.2.1 <br />
<br />
<br />
<br />
<br />
<br />
<br />
<strong>wxPython</strong><br />
12<br />
<br />
wx.ImageList<br />
wx.ImageList(width, height, mask=True, <strong>in</strong>itialCount=1)<br />
404 / 565
widthheight<br />
maskTrue<br />
<strong>in</strong>itialCount<br />
<br />
<br />
Add(bitmap, mask=wx.NullBitmap)<br />
bitmapmaskwx.Bitmapmask<br />
mask<br />
<br />
<br />
AddWithColourMask(bitmapcolour)colour<br />
<strong>wxPython</strong>wx.Icon<br />
AddIcon(icon)<br />
<br />
13.1<br />
il = wx.ImageList(32, 32, True)<br />
for name <strong>in</strong> glob.glob(“icon.png”):<br />
bmp = wx.Bitmap(name, wx.BITMAP_TYPE_PNG)<br />
il_max = il.Add(bmp)<br />
<br />
self.list.AssignImageList(il, wx.IMAGE_LIST_NORMAL)<br />
Remove(<strong>in</strong>dex)<strong>in</strong>dex<br />
<br />
<br />
RemoveAll()<br />
Replace(<strong>in</strong>dex, bitmap, mask=wx.NullBitmap)<br />
<strong>in</strong>dexbitmapmaskAdd()<br />
ReplaceIcon(<strong>in</strong>dex, icon)<br />
<br />
405 / 565
GetImageCount()<br />
GetSize()(width, height)<br />
<br />
<br />
6<br />
12Draw<br />
Draw(<strong>in</strong>dex, dc, x, y, flags=wx.IMAGELIST_DRAW_NORMAL,<br />
solid”302.files/”><br />
<strong>in</strong>dexdc<br />
wx.DCflagsflags<br />
<br />
wx.IMAGELIST_DRAW_NORMAL, wx.IMAGELIST_DRAW_TRANSPARENT,<br />
wx.IMAGELISTDRAW_SelectED, wx.IMAGELIST_DRAW_FOCUSED<br />
solidBackgroundTrue<br />
<br />
AssignImage(imageList, which)<br />
SetImage(imageList, which)imageListwhich<br />
wx.IMAGE_LIST_NORMAL wx.IMAGE_LIST_SMALL<br />
C++AssignImage()<br />
SetImage()<br />
<br />
Python<br />
<br />
wx.IMAGE_LIST_NORMAL<br />
wx.IMAGE_LIST_SMALL<br />
<br />
<br />
<br />
<br />
<br />
get*GetImageList(which)<br />
which<br />
406 / 565
13.2.2 <br />
<br />
<br />
/<br />
API<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
InsertItem()<br />
<br />
InsertStr<strong>in</strong>gItem(<strong>in</strong>dex, label)<strong>in</strong>dex<br />
InsertImageItem(<strong>in</strong>dex, imageIndex)<br />
<strong>in</strong>deximageIndex<br />
<br />
<br />
<br />
InsertImageStr<strong>in</strong>gItem(<strong>in</strong>dex, label, imageIndex)<br />
<br />
wx.ListItem<br />
InsertItem(<strong>in</strong>dex, item)<br />
itemwx.ListItemwx.ListItem<br />
——<br />
get*set*<br />
<br />
<br />
/<br />
InsertColumn()<br />
InsertColumn(col, head<strong>in</strong>g, format=wx.LIST_FORMAT_LEFT, width=-1)<br />
407 / 565
col<br />
head<strong>in</strong>gformat<br />
wx.LIST_FORMAT_CENTREwx.LIST_FORMAT_LEFT<br />
wx.LIST_FORMAT_RIGHT<br />
width——<br />
wx.ListItem<br />
InsertColumnInfo(<strong>in</strong>fo)<br />
<br />
<br />
<br />
SetStr<strong>in</strong>gItem()<br />
SetStr<strong>in</strong>gItem(<strong>in</strong>dex, col, label, imageId=-1)<br />
<strong>in</strong>dexcolcol0<br />
<strong>in</strong>dex——<br />
labelimageId<br />
<br />
<br />
SetStr<strong>in</strong>gItem()SetItem(<strong>in</strong>fo)SetItem(<strong>in</strong>fo)<br />
wx.ListItemwx.ListItem<br />
GetItem(<strong>in</strong>dex,col=0)<br />
wx.ListItem<br />
col<br />
<br />
get*set*<br />
GetItem()<br />
get*set*SetItemImage(item, image, selImage)<br />
itemimage<br />
selImage<br />
GetItemText(item)SetItemText(item,text)<br />
<br />
408 / 565
GetItemState(item,stateMask)<br />
SetItemState(item, state, stateMask)state<br />
stateMask13.3stateGetItemState<br />
stateMask<br />
GetColumn(col)col<br />
wx.ListItem<br />
13.3 <br />
<br />
wx.LIST_STATE_CUTW<strong>in</strong>dows<br />
wx.LIST_STATE_DONTCAREW<strong>in</strong>dows<br />
wx.LIST_STATE_DropHILITED<br />
W<strong>in</strong>dows<br />
wx.LIST_STATE_FOCUSED<br />
wx.LIST_STATE_SelectED<br />
SetColumn(col, item)<br />
GetColumnWidth(col)<br />
——<br />
SetColumnWidth(col,width)width<br />
wx.LIST_AUTOSIZE<br />
wx.LIST_AUTOSIZE_USEHEADER<br />
W<strong>in</strong>dows<br />
wx.LIST_AUTOSIZE_USEHEADER80<br />
<br />
GetColumnCount()GetItemCount()<br />
GetCountPerPage()<br />
<br />
DeleteItem(item)item<br />
DeleteAllItems()<br />
ClearAll()DeleteColumn(col)col<br />
409 / 565
13.3 <br />
<br />
<br />
<br />
13.3.1 <br />
<br />
B<strong>in</strong>d()<br />
wx.ListEvent<br />
wx.ListEventwx.CommandEventwx.ListEventget*<br />
<br />
13.4<br />
13.4 wx.ListEvent<br />
GetData()<br />
GetKeyCode()<br />
GetIndex()<br />
GetItem()wx.ListItem<br />
GetImage()<br />
GetMask()<br />
GetPo<strong>in</strong>t()<br />
GetText()<br />
wx.ListEvent<br />
13.5<br />
<br />
13.5 <br />
EVT_LIST_BEGIN_DRAG<br />
<br />
410 / 565
EVT_LIST_BEGIN_RDRAG<br />
<br />
EVT_LIST_Delete_ALL_ITEMS DeleteAll()<br />
EVT_LIST_Delete_ITEM Delete()<br />
EVT_LIST_Insert_ITEM<br />
EVT_LIST_ITEM_ACTIVATED<br />
<br />
EVT_LIST_ITEM_DESelectED<br />
EVT_LIST_ITEM_FOCUSED<br />
EVT_LIST_ITEM_MIDDLE_CLICK<br />
<br />
EVT_LIST_ITEM_RIGHT_CLICK<br />
EVT_LIST_ITEM_SelectED<br />
<br />
EVT_LIST_ITEM_KEY_DOWN<br />
<br />
13.3<br />
13.3.2 <br />
<br />
wx.ListEventGetColumn()<br />
<br />
<br />
113.6<br />
13.6 <br />
EVT_LIST_COL_BEGIN_DRAG<br />
EVT_LIST_COL_CLICK<br />
EVT_LIST_COL_RIGHT_CLICK<br />
411 / 565
EVT_LiST_COL_END_DRAG<br />
13.3<br />
13.3 <br />
import wx<br />
import sys, glob, random<br />
import data<br />
class DemoFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, -1,<br />
”Other wx.ListCtrl Stuff”,<br />
size=(700,500))<br />
self.list = None<br />
self.editable = False<br />
self.MakeMenu()<br />
self.MakeListCtrl()<br />
def MakeListCtrl(self, otherflags=0):<br />
# if we already have a listctrl then get rid of it<br />
if self.list:<br />
self.list.Destroy()<br />
if self.editable:<br />
otherflags |= wx.LC_EDIT_LABELS<br />
# load some images <strong>in</strong>to an image list<br />
il = wx.ImageList(16,16, True)<br />
for name <strong>in</strong> glob.glob(“smicon.png”):<br />
bmp = wx.Bitmap(name, wx.BITMAP_TYPE_PNG)<br />
il_max = il.Add(bmp)<br />
# create the list control<br />
self.list = wx.ListCtrl(self, -1, style=wx.LC_REPORT|otherflags)<br />
# assign the image list to it<br />
412 / 565
self.list.AssignImageList(il, wx.IMAGE_LIST_SMALL)<br />
# Add some columns<br />
for col, text <strong>in</strong> enumerate(data.columns):<br />
self.list.InsertColumn(col, text)<br />
# add the rows<br />
for row, item <strong>in</strong> enumerate(data.rows):<br />
<strong>in</strong>dex = self.list.InsertStr<strong>in</strong>gItem(sys.max<strong>in</strong>t, item[0])<br />
for col, text <strong>in</strong> enumerate(item[1:]):<br />
self.list.SetStr<strong>in</strong>gItem(<strong>in</strong>dex, col+1, text)<br />
# give each item a random image<br />
img = random.rand<strong>in</strong>t(0, il_max)<br />
self.list.SetItemImage(<strong>in</strong>dex, img, img)<br />
# set the data value for each item to be its position <strong>in</strong><br />
# the data list<br />
self.list.SetItemData(<strong>in</strong>dex, row)<br />
# set the width of the columns <strong>in</strong> various ways<br />
self.list.SetColumnWidth(0, 120)<br />
self.list.SetColumnWidth(1, wx.LIST_AUTOSIZE)<br />
self.list.SetColumnWidth(2, wx.LIST_AUTOSIZE)<br />
self.list.SetColumnWidth(3, wx.LIST_AUTOSIZE_USEHEADER)<br />
# b<strong>in</strong>d some <strong>in</strong>terest<strong>in</strong>g events<br />
self.B<strong>in</strong>d(wx.EVT_LIST_ITEM_SelectED, self.OnItemSelected, self.list)<br />
self.B<strong>in</strong>d(wx.EVT_LIST_ITEM_DESelectED, self.OnItemDeselected, self.list)<br />
self.B<strong>in</strong>d(wx.EVT_LIST_ITEM_ACTIVATED, self.OnItemActivated, self.list)<br />
# <strong>in</strong> case we are recreat<strong>in</strong>g the list tickle the frame a bit so<br />
# it will redo the layout<br />
self.SendSizeEvent()<br />
def MakeMenu(self):<br />
mbar = wx.MenuBar()<br />
menu = wx.Menu()<br />
413 / 565
item = menu.Append(-1, ”E&xit\tAlt-X”)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnExit, item)<br />
mbar.Append(menu, ”&File”)<br />
menu = wx.Menu()<br />
item = menu.Append(-1, ”Sort ascend<strong>in</strong>g”)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnSortAscend<strong>in</strong>g, item)<br />
item = menu.Append(-1, ”Sort descend<strong>in</strong>g”)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnSortDescend<strong>in</strong>g, item)<br />
item = menu.Append(-1, ”Sort by submitter”)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnSortBySubmitter, item)<br />
menu.AppendSeparator()<br />
item = menu.Append(-1, ”Show selected”)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnShowSelected, item)<br />
item = menu.Append(-1, ”Select all”)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnSelectAll, item)<br />
item = menu.Append(-1, ”Select none”)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnSelectNone, item)<br />
menu.AppendSeparator()<br />
item = menu.Append(-1, ”Set item text colour”)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnSetTextColour, item)<br />
item = menu.Append(-1, ”Set item background colour”)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnSetBGColour, item)<br />
menu.AppendSeparator()<br />
item = menu.Append(-1, ”Enable item edit<strong>in</strong>g”, k<strong>in</strong>d=wx.ITEM_CHECK)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnEnableEdit<strong>in</strong>g, item)<br />
item = menu.Append(-1, ”Edit current item”)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnEditItem, item)<br />
mbar.Append(menu, ”&Demo”)<br />
self.SetMenuBar(mbar)<br />
def OnExit(self, evt):<br />
self.Close()<br />
414 / 565
def OnItemSelected(self, evt):<br />
item = evt.GetItem()<br />
pr<strong>in</strong>t ”Item selected:”, item.GetText()<br />
def OnItemDeselected(self, evt):<br />
item = evt.GetItem()<br />
pr<strong>in</strong>t ”Item deselected:”, item.GetText()<br />
def OnItemActivated(self, evt):<br />
item = evt.GetItem()<br />
pr<strong>in</strong>t ”Item activated:”, item.GetText()<br />
def OnSortAscend<strong>in</strong>g(self, evt):<br />
# recreate the listctrl with a sort style<br />
self.MakeListCtrl(wx.LC_SORT_ASCENDING)<br />
def OnSortDescend<strong>in</strong>g(self, evt):<br />
# recreate the listctrl with a sort style<br />
self.MakeListCtrl(wx.LC_SORT_DESCENDING)<br />
def OnSortBySubmitter(self, evt):<br />
def compare_func(row1, row2):<br />
# compare the values <strong>in</strong> the 4th col of the data<br />
val1 = data.rows[row1][3]<br />
val2 = data.rows[row2][3]<br />
if val1 < val2: return -1<br />
if val1 > val2: return 1<br />
return 0<br />
self.list.SortItems(compare_func)<br />
def OnShowSelected(self, evt):<br />
pr<strong>in</strong>t ”These items are selected:”<br />
<strong>in</strong>dex = self.list.GetFirstSelected()<br />
if <strong>in</strong>dex == -1:<br />
pr<strong>in</strong>t ”\tNone”<br />
return<br />
415 / 565
while <strong>in</strong>dex != -1:<br />
item = self.list.GetItem(<strong>in</strong>dex)<br />
pr<strong>in</strong>t ”\t%s” % item.GetText()<br />
<strong>in</strong>dex = self.list.GetNextSelected(<strong>in</strong>dex)<br />
def OnSelectAll(self, evt):<br />
for <strong>in</strong>dex <strong>in</strong> range(self.list.GetItemCount()):<br />
self.list.Select(<strong>in</strong>dex, True)<br />
def OnSelectNone(self, evt):<br />
<strong>in</strong>dex = self.list.GetFirstSelected()<br />
while <strong>in</strong>dex != -1:<br />
self.list.Select(<strong>in</strong>dex, False)<br />
<strong>in</strong>dex = self.list.GetNextSelected(<strong>in</strong>dex)<br />
def OnSetTextColour(self, evt):<br />
dlg = wx.ColourDialog(self)<br />
if dlg.ShowModal() == wx.ID_OK:<br />
colour = dlg.GetColourData().GetColour()<br />
<strong>in</strong>dex = self.list.GetFirstSelected()<br />
while <strong>in</strong>dex != -1:<br />
self.list.SetItemTextColour(<strong>in</strong>dex, colour)<br />
<strong>in</strong>dex = self.list.GetNextSelected(<strong>in</strong>dex)<br />
dlg.Destroy()<br />
def OnSetBGColour(self, evt):<br />
dlg = wx.ColourDialog(self)<br />
if dlg.ShowModal() == wx.ID_OK:<br />
colour = dlg.GetColourData().GetColour()<br />
<strong>in</strong>dex = self.list.GetFirstSelected()<br />
while <strong>in</strong>dex != -1:<br />
self.list.SetItemBackgroundColour(<strong>in</strong>dex, colour)<br />
<strong>in</strong>dex = self.list.GetNextSelected(<strong>in</strong>dex)<br />
dlg.Destroy()<br />
def OnEnableEdit<strong>in</strong>g(self, evt):<br />
self.editable = evt.IsChecked()<br />
self.MakeListCtrl()<br />
416 / 565
def OnEditItem(self, evt):<br />
<strong>in</strong>dex = self.list.GetFirstSelected()<br />
if <strong>in</strong>dex != -1:<br />
self.list.EditLabel(<strong>in</strong>dex)<br />
class DemoApp(wx.App):<br />
def OnInit(self):<br />
frame = DemoFrame()<br />
self.SetTopW<strong>in</strong>dow(frame)<br />
pr<strong>in</strong>t ”Program output appears here...”<br />
frame.Show()<br />
return True<br />
app = DemoApp(redirect=True)<br />
app.Ma<strong>in</strong>Loop()<br />
<br />
<br />
13.4 <br />
<br />
13.4.1 <br />
<br />
<br />
<br />
<br />
wx.LC_EDIT_LABELS<br />
list = wx.ListCtrl(self, -1, style=wx.LC_REPORT | wx.LC_EDIT_LABELS)<br />
<br />
Enter<br />
<br />
417 / 565
Esc<br />
<br />
<br />
* EVT_LIST_BEGIN_LABEL_EDIT<br />
* EVT_LIST_END_LABEL_EDIT<br />
<br />
Skip()<br />
EVT_LIST_BEGIN_LABEL_EDIT<br />
EnterEscEVT_LIST_END_LABEL_EDIT<br />
(veto)<br />
<br />
wx.ListEvent<br />
EVT_LIST_END_LABEL_EDIT<br />
GetLabel()Esc<br />
GetLabel()GetLabel()“<br />
”“”<br />
IsEditCancelled()TrueFalse<br />
<br />
EditLabel(item)item<br />
EVT_LIST_BEGIN_LABEL_EDIT<br />
<br />
GetEditControl()<br />
NoneW<strong>in</strong>dows<br />
<br />
13.4.2 <br />
<strong>wxPython</strong><br />
<br />
418 / 565
wx.LC_SORT_ASCENDING<br />
wx.LC_SORT_DESCENDING<br />
W<strong>in</strong>dows<br />
<br />
<br />
<br />
<br />
<br />
<strong>wxPython</strong><br />
SetItemData(item, data)item<br />
dataC<br />
++<br />
GetItemData(item)<br />
SortItems(func)<br />
funcPythonfunc<br />
——<br />
<br />
0<br />
<br />
<br />
<br />
<br />
<br />
SortItems()<br />
<br />
ColumnSorterMix<strong>in</strong><strong>wxPython</strong>mix<strong>in</strong><br />
wx.lib.mix<strong>in</strong>s.listctrl13.5mix<strong>in</strong><br />
419 / 565
13.5<br />
mix<strong>in</strong>Python<br />
import wx.lib.mix<strong>in</strong>s.listctrl as listmix<br />
class ListCtrlPanel(wx.Panel, listmix.ColumnSorterMix<strong>in</strong>):<br />
def __<strong>in</strong>it__(self, parent, log):<br />
wx.Panel.__<strong>in</strong>it__(self, parent, -1, style=wx.WANTS_CHARS)<br />
self.list = TestListCtrl(self, tID)<br />
self.itemDataMap = musicdata<br />
listmix.ColumnSorterMix<strong>in</strong>.__<strong>in</strong>it__(self, 3)<br />
13.413.5<br />
13.4mix<strong>in</strong><br />
#!/usr/b<strong>in</strong>/python<br />
#-*- encod<strong>in</strong>g:UTF-8 -*-<br />
import wx<br />
import wx.lib.mix<strong>in</strong>s.listctrl<br />
import sys, glob, random<br />
import data<br />
class DemoFrame(wx.Frame, wx.lib.mix<strong>in</strong>s.listctrl.ColumnSorterMix<strong>in</strong>):#<br />
<br />
420 / 565
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, -1,<br />
”wx.ListCtrl with ColumnSorterMix<strong>in</strong>”,<br />
size=(600,400))<br />
# load some images <strong>in</strong>to an image list<br />
il = wx.ImageList(16,16, True)<br />
for name <strong>in</strong> glob.glob(“smicon.png”):<br />
bmp = wx.Bitmap(name, wx.BITMAP_TYPE_PNG)<br />
il_max = il.Add(bmp)<br />
# add some arrows for the column sorter<br />
#<br />
self.up = il.AddWithColourMask(<br />
wx.Bitmap(“sm_up.bmp”, wx.BITMAP_TYPE_BMP), ”blue”)<br />
self.dn = il.AddWithColourMask(<br />
wx.Bitmap(“sm_down.bmp”, wx.BITMAP_TYPE_BMP), ”blue”)<br />
# create the list control<br />
self.list = wx.ListCtrl(self, -1, style=wx.LC_REPORT)<br />
# assign the image list to it<br />
self.list.AssignImageList(il, wx.IMAGE_LIST_SMALL)<br />
# Add some columns<br />
for col, text <strong>in</strong> enumerate(data.columns):<br />
self.list.InsertColumn(col, text)<br />
# add the rows<br />
#<br />
self.itemDataMap = {}<br />
for item <strong>in</strong> data.rows:<br />
<strong>in</strong>dex = self.list.InsertStr<strong>in</strong>gItem(sys.max<strong>in</strong>t, item[0])<br />
for col, text <strong>in</strong> enumerate(item[1:]):<br />
self.list.SetStr<strong>in</strong>gItem(<strong>in</strong>dex, col+1, text)<br />
# give each item a data value, and map it back to the<br />
# item values, for the column sorter<br />
self.list.SetItemData(<strong>in</strong>dex, <strong>in</strong>dex)#<br />
self.itemDataMap[<strong>in</strong>dex] = item<br />
421 / 565
# give each item a random image<br />
img = random.rand<strong>in</strong>t(0, il_max)<br />
self.list.SetItemImage(<strong>in</strong>dex, img, img)<br />
# set the width of the columns <strong>in</strong> various ways<br />
self.list.SetColumnWidth(0, 120)<br />
self.list.SetColumnWidth(1, wx.LIST_AUTOSIZE)<br />
self.list.SetColumnWidth(2, wx.LIST_AUTOSIZE)<br />
self.list.SetColumnWidth(3, wx.LIST_AUTOSIZE_USEHEADER)<br />
# <strong>in</strong>itialize the column sorter<br />
wx.lib.mix<strong>in</strong>s.listctrl.ColumnSorterMix<strong>in</strong>.__<strong>in</strong>it__(self,<br />
len(data.columns))<br />
def GetListCtrl(self):<br />
return self.list<br />
def GetSortImages(self):<br />
return (self.dn, self.up)<br />
app = wx.PySimpleApp()<br />
frame = DemoFrame()<br />
frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
mix<strong>in</strong><br />
1ColumnSorterMix<strong>in</strong>DemoFrame<br />
GetListCtrl()mix<strong>in</strong><br />
<br />
2ColumnSorterMix<strong>in</strong>DemoFrame__<strong>in</strong>it__()<br />
ColumnSorterMix<strong>in</strong>__<strong>in</strong>it__()<br />
GetListCtrl()mix<strong>in</strong>__<strong>in</strong>it__()<br />
<br />
3SetItemData()<br />
422 / 565
4ColumnSorterMix<strong>in</strong>DemoFrame<br />
itemDataMap<br />
SetItemData()<br />
itemDataMap<br />
<br />
ColumnSorterMix<strong>in</strong>itemDataMap<br />
itemDataMap<br />
<br />
ColumnSorterMix<strong>in</strong><br />
<br />
13.4.3 <br />
<br />
<br />
<br />
<br />
13.7<br />
13.8HitTest()<br />
<br />
13.7 <br />
F<strong>in</strong>dItem(start, str, partial=False)strstart1<br />
startpartialTrue<br />
str<br />
F<strong>in</strong>dItemAtPos(startpo<strong>in</strong>t, direction)po<strong>in</strong>tpo<strong>in</strong>t<br />
wx.Po<strong>in</strong>tdirection<br />
<br />
wx.LIST_FIND_DOWN, wx.LIST_FIND_LEFT, wx.LIST_FIND_RIGHT, <br />
wx.LIST_FIND_UP<br />
F<strong>in</strong>dItemData(start,data)SetItemData()data<br />
startF<strong>in</strong>dItem()<br />
423 / 565
HitTest(po<strong>in</strong>t)(<strong>in</strong>dex, flags)Python<strong>in</strong>dex<br />
<strong>in</strong>dex1flags<br />
flags13.8<br />
13.8 HitTest()<br />
wx.LIST_HITTEST_ABOVE<br />
wx.LIST_HITTEST_BELOW<br />
wx.LIST_HITTEST_NOWhere<br />
<br />
wx.LIST_HITTEST_ONITEM(<strong>in</strong>dex, flags)<strong>in</strong>dex<br />
<br />
wx.LIST_HITTEST_ONITEMICON(<strong>in</strong>dex, flags)<br />
<strong>in</strong>dex<br />
wx.LIST_HITTEST_ONITEMLABEL(<strong>in</strong>dex, flags)<br />
<strong>in</strong>dex<br />
wx.LIST_HITTEST_ONITEMRIGHT<br />
wx.LIST_HITTEST_ONITEMSTATEICON<br />
<br />
wx.LIST_HITTEST_TOLEFT<br />
wx.LIST_HITTEST_TORIGHT<br />
<br />
GetItem()GetItemText()13.9<br />
13.9 <br />
GetItemPosition(item)wx.Po<strong>in</strong>t<br />
<br />
GetItemRect(item,code= wx.LIST_RECT_BOUNDS)item<br />
wx.Rectcodecode<br />
wx.LIST_RECT_BOUNDS<strong>wxPython</strong>code<br />
wx.LIST_RECT_ICON<br />
wx.LIST_RECT_LABEL<br />
424 / 565
GetNextItem(item, geometry=wx.LIST_ALL, state=wx.LIST_STATE_DONTCARE )<br />
geometrystateitem<br />
geometrystate<br />
SetItemPosition(item, pos)itempos<br />
<br />
13.10GetNextItem()geometrygeometry<br />
W<strong>in</strong>dows<br />
13.10 GetNextItem()geometry<br />
wx.LIST_NEXT_ABOVE<br />
<br />
wx.LIST_NEXT_ALL<br />
wx.LIST_NEXT_BELOW<br />
<br />
wx.LIST_NEXT_LEFT<br />
wx.LIST_NEXT_RIGHT<br />
<br />
13.11GetNextItem()state<br />
13.11 GetNextItem()state<br />
wx.LIST_STATE_CUT<br />
wx.LIST_STATE_DONTCARE<br />
wx.LIST_STATE_DropHILITED<br />
wx.LIST_STATE_FOCUSED<br />
wx.LIST_STATE_SelectED<br />
13.12<br />
<br />
425 / 565
13.2 <br />
GetBackgroundColour()<br />
SetBackgroundColour(col)colwx.Colour<br />
<br />
GetItemBackgroundColour(item)<br />
SetItemBackgroundColour(item,col)item<br />
<br />
GetItemTextColour(item)<br />
SetItemTextColour(item, col)item<br />
<br />
GetTextColour()<br />
SetTextColour(col)<br />
13.3<br />
13.3 <br />
GetItemSpac<strong>in</strong>g()wx.Size<br />
GetSelectedItemCount()<br />
GetTopItem()<br />
GetViewRect()wx.Rect<br />
<br />
ScrollList(dx, dy)dydx<br />
<br />
<br />
<br />
<br />
<br />
13.5 <br />
<strong>wxPython</strong><br />
<br />
426 / 565
<strong>wxPython</strong><br />
<br />
<br />
<br />
13.6<br />
13.6<br />
13.5<br />
13.5 <br />
#!/usr/b<strong>in</strong>/python<br />
#-*- encod<strong>in</strong>g:UTF-8 -*-<br />
import wx<br />
import sys, glob, random<br />
427 / 565
import data<br />
class DataSource:#<br />
”””<br />
A simple data source class that just uses our sample data items.<br />
A real data source class would manage fetch<strong>in</strong>g items from a<br />
database or similar.<br />
”””<br />
def GetColumnHeaders(self):<br />
return data.columns<br />
def GetCount(self):<br />
return len(data.rows)<br />
def GetItem(self, <strong>in</strong>dex):<br />
return data.rows[<strong>in</strong>dex]<br />
def UpdateCache(self, start, end):<br />
pass<br />
class VirtualListCtrl(wx.ListCtrl):#1 <br />
”””<br />
A generic virtual listctrl that fetches data from a DataSource.<br />
”””<br />
def __<strong>in</strong>it__(self, parent, dataSource):<br />
wx.ListCtrl.__<strong>in</strong>it__(self, parent,<br />
style=wx.LC_REPORT|wx.LC_SINGLE_SEL|wx.LC_VIRTUAL)#<br />
wx.LC_VIRTUAL<br />
self.dataSource = dataSource<br />
self.B<strong>in</strong>d(wx.EVT_LIST_CACHE_HINT, self.DoCacheItems)<br />
self.SetItemCount(dataSource.GetCount())#<br />
columns = dataSource.GetColumnHeaders()<br />
for col, text <strong>in</strong> enumerate(columns):<br />
self.InsertColumn(col, text)<br />
def DoCacheItems(self, evt):<br />
self.dataSource.UpdateCache(<br />
428 / 565
evt.GetCacheFrom(), evt.GetCacheTo())<br />
def OnGetItemText(self, item, col):#<br />
data = self.dataSource.GetItem(item)<br />
return data[col]<br />
def OnGetItemAttr(self, item): return None<br />
def OnGetItemImage(self, item): return -1<br />
class DemoFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, -1,<br />
”Virtual wx.ListCtrl”,<br />
size=(600,400))<br />
self.list = VirtualListCtrl(self, DataSource())<br />
app = wx.PySimpleApp()<br />
frame = DemoFrame()<br />
frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
<br />
<br />
<br />
<br />
wx.LC_VIRTUAL#1wx.ListCtrl<br />
wx.ListCtrl<br />
<br />
class MyVirtualList(wx.ListCtrl):<br />
def __<strong>in</strong>it__(self, parent):<br />
wx.ListCtrl.__<strong>in</strong>it__(self, parent, -1,<br />
style=wx.LC_REPORT|wx.LC_VIRTUAL)<br />
429 / 565
SetItemCount()<br />
<br />
SetItemCount()<br />
On[0,SetItemCount()1]<br />
<br />
OnGetItemText(item, col)item<br />
col<br />
<br />
def OnGetItemText(self, item, col):<br />
return ”Item %d, column %d” % (item, col)<br />
OnGetItemImage(item)<br />
<br />
OnGetItemImage1<br />
OnGetItemAttr(item)<br />
itemwx.ListItemAttr<br />
get*set*<br />
<br />
RefreshItem(item)<br />
RefreshItems(itemFrom,itemTo)itemFromitemTo<br />
<br />
EVT_LIST_CACHE_HINT<br />
<br />
OnGetItemText()<br />
13.6 <br />
1<strong>wxPython</strong><br />
wx.ListCtrl<br />
<br />
<br />
<br />
430 / 565
2<br />
<br />
<br />
3InsertStr<strong>in</strong>gItem(<strong>in</strong>dex,label)<br />
InsertImageItem(<strong>in</strong>dex, imageIndex)<br />
InsertImageStr<strong>in</strong>gItem(<strong>in</strong>dex,label,<br />
imageIndex)<br />
InsertColumn(col, head<strong>in</strong>g, format=”wx.LIST_FORMAT_LEFT, width=-1)<br />
SetStr<strong>in</strong>gItem(<strong>in</strong>dex, col, label, imageId=-1)<br />
<br />
4<br />
wx.ListEvent<br />
EVT_LIST_Insert_ITEM, EVT_LIST_ITEM_ACTIVATED,<br />
EVT_LIST_ ITEM_SelectED<br />
5wx.LC_EDIT_LABELS<br />
<br />
Esc<br />
6wx.LC_SORT_ASCENDING<br />
wx.LC_SORT_DESCENDING<br />
0<br />
SortItems(func)mix<strong>in</strong><br />
wx.lib.mix<strong>in</strong>s.listctrl.ColumnSorterMix<strong>in</strong><br />
<br />
7wx.LC_VIRTUAL<br />
<br />
OnGetItemText(item, col)<br />
OnGetItemImage(item)OnGetItemAttr(item)<br />
<br />
RefreshItem(item)<br />
RefreshItems(itemFrom, itemTo)<br />
<br />
<br />
431 / 565
14 (grid)<br />
:<br />
(grid)<br />
(cell),<br />
(cell)(renderer)<br />
<br />
<br />
<strong>wxPython</strong><br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<strong>wxPython</strong><br />
14.1 <br />
<br />
<strong>wxPython</strong><br />
<br />
<br />
* <br />
432 / 565
* (grid table)<br />
<br />
<br />
<br />
5MVC<br />
<br />
14.1.1 <br />
<br />
14.1<br />
<br />
14.1<br />
wx.grid.Grid<br />
<strong>wxPython</strong><br />
wx.grid.Grid<br />
<br />
wx.grid.Grid(parent, id, pos=wx.DefaultPosition,<br />
433 / 565
size=wx.DefaultSize, style=wx.WANTS_CHARS,<br />
name=wxPanelNameStr)<br />
wx.W<strong>in</strong>dow<br />
wx.WANTS_CHARSwx.grid.Grid<br />
<br />
wx.grid.Grid<br />
<br />
<br />
* CreateGrid()<br />
* SetTable()<br />
<br />
<br />
CreateGrid(numRows, numCols, selmode=wx.grid.Grid.SelectCells)<br />
<br />
numRows, numColsselmode<br />
wx.grid.Grid.SelectCells<br />
wx.grid.Grid.SelectRows<br />
wx.grid.Grid.SelectionColumns<br />
GetSelectionMode()<br />
SetSelectionMode(mode)GetNumberCols()<br />
GetNumberRows()<br />
CreateGrid()<strong>wxPython</strong><br />
SetCellValue(row, col, s)<br />
row, cols<br />
<br />
GetCellValue(row, col)<br />
ClearGrid()14.114.1<br />
14.1 ClearGrid()<br />
import wx<br />
import wx.grid<br />
class TestFrame(wx.Frame):<br />
434 / 565
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, title=”Simple Grid”,<br />
size=(640,480))<br />
grid = wx.grid.Grid(self)<br />
grid.CreateGrid(50,50)<br />
for row <strong>in</strong> range(20):<br />
for col <strong>in</strong> range(6):<br />
grid.SetCellValue(row, col,<br />
”cell (%d,%d)” % (row, col))<br />
app = wx.PySimpleApp()<br />
frame = TestFrame()<br />
frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
CreateGrid()SetCellValue()<br />
<br />
<br />
14.1.2 <br />
<br />
<br />
<br />
* <br />
* <br />
* <br />
5MVC<br />
<br />
14.2<br />
435 / 565
14.2<br />
wx.grid.PyGridTableBase<br />
wx.grid.GridTableBase14.214.2<br />
<br />
14.2 <br />
#-*- encod<strong>in</strong>g:UTF-8 -*-<br />
import wx<br />
import wx.grid<br />
class TestTable(wx.grid.PyGridTableBase):#<br />
def __<strong>in</strong>it__(self):<br />
wx.grid.PyGridTableBase.__<strong>in</strong>it__(self)<br />
self.data = { (1,1) : ”Here”,<br />
(2,2) : ”is”,<br />
(3,3) : ”some”,<br />
(4,4) : ”data”,<br />
}<br />
self.odd=wx.grid.GridCellAttr()<br />
self.odd.SetBackgroundColour(“sky blue”)<br />
self.odd.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD))<br />
436 / 565
self.even=wx.grid.GridCellAttr()<br />
self.even.SetBackgroundColour(“sea green”)<br />
self.even.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD))<br />
# these five are the required methods<br />
def GetNumberRows(self):<br />
return 50<br />
def GetNumberCols(self):<br />
return 50<br />
def IsEmptyCell(self, row, col):<br />
return self.data.get((row, col)) is not None<br />
def GetValue(self, row, col):#<br />
value = self.data.get((row, col))<br />
if value is not None:<br />
return value<br />
else:<br />
return ’’<br />
def SetValue(self, row, col, value):#<br />
self.data[(row,col)] = value<br />
# the table can also provide the attribute for each cell<br />
def GetAttr(self, row, col, k<strong>in</strong>d):<br />
attr = [self.even, self.odd][row % 2]<br />
attr.IncRef()<br />
return attr<br />
class TestFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, title=”Grid Table”,<br />
size=(640,480))<br />
437 / 565
grid = wx.grid.Grid(self)<br />
table = TestTable()<br />
grid.SetTable(table, True)<br />
app = wx.PySimpleApp()<br />
frame = TestFrame()<br />
frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
14.2<br />
wx.grid.Grid<br />
514.1<br />
<br />
<br />
14.1 wx.grid.GridTableBase<br />
GetNumberCols()<br />
GetNumberRows()<br />
GetValue(row, col)(row, col)<br />
IsEmptyCell(row, col)(row, col)True<br />
False<br />
SetValue(row, col, value)<br />
pass<br />
<br />
<br />
SetTable(table,takeOwnership=False,selmode=wx.grid.Grid.SelectCells)<br />
tablewx.grid.PyGridTableBasetakeOwnership<br />
takeOwnershipTrue<br />
<strong>wxPython</strong>selmodeCreateGrid()<br />
<br />
<br />
438 / 565
SetTableCreateGrid()<br />
<br />
Clear()ClearGrid()<br />
<br />
<br />
<br />
14.2 <br />
<br />
<br />
<br />
<br />
14.2.1 <br />
<br />
AppendCols(numCols=1)<br />
AppendRows(numRows=1)<br />
<br />
<br />
InsertCols(pos=0, numCols=1)InsertRows(pos=1, numRows=1)<br />
posnumRows<br />
numCols1 <br />
<br />
DeleteCols(pos=0, numCols=1)<br />
DeleteRows(pos=0, numRows=1)pos<br />
<br />
CreateGrid()<br />
<br />
SetTable()<br />
<br />
<br />
InsertCols()<br />
InsertCols(pos=0, numCols=1)True<br />
439 / 565
False50<br />
<br />
def AppendRows(self, numRows=1):<br />
return (self.GetRowCount() + numRows)
14.3 <br />
import wx<br />
import wx.grid<br />
class TestFrame(wx.Frame):<br />
rowLabels = [“uno”, ”dos”, ”tres”, ”quatro”, ”c<strong>in</strong>co”]<br />
colLabels = [“homer”, ”marge”, ”bart”, ”lisa”, ”maggie”]<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, title=”Grid Headers”,<br />
size=(500,200))<br />
grid = wx.grid.Grid(self)<br />
grid.CreateGrid(5,5)<br />
for row <strong>in</strong> range(5):<br />
#1 start<br />
grid.SetRowLabelValue(row, self.rowLabels[row])<br />
grid.SetColLabelValue(row, self.colLabels[row])<br />
#1 end<br />
for col <strong>in</strong> range(5):<br />
grid.SetCellValue(row, col,<br />
”(%s,%s)” % (self.rowLabels[row], self.colLabels[col]))<br />
app = wx.PySimpleApp()<br />
frame = TestFrame()<br />
frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
<br />
CreateGrid()SetColLabelValue(col, value)<br />
SetRowLabelValue(row, value)#1colrow<br />
value<br />
GetColLabelValue(col)GetRowLabelValue(row)<br />
<br />
GetColLabelValue(col)GetRowLabelValue(row)<br />
<br />
<br />
set*set*——<br />
441 / 565
SetColLabelValue(col, value)SetRowLabelValue(row, value)——<br />
set*14.4<br />
——<br />
14.4 <br />
import wx<br />
import wx.grid<br />
class TestTable(wx.grid.PyGridTableBase):<br />
def __<strong>in</strong>it__(self):<br />
wx.grid.PyGridTableBase.__<strong>in</strong>it__(self)<br />
self.rowLabels = [“uno”, ”dos”, ”tres”, ”quatro”, ”c<strong>in</strong>co”]<br />
self.colLabels = [“homer”, ”marge”, ”bart”, ”lisa”, ”maggie”]<br />
def GetNumberRows(self):<br />
return 5<br />
def GetNumberCols(self):<br />
return 5<br />
def IsEmptyCell(self, row, col):<br />
return False<br />
def GetValue(self, row, col):<br />
return ”(%s,%s)” % (self.rowLabels[row], self.colLabels[col])<br />
def SetValue(self, row, col, value):<br />
pass<br />
def GetColLabelValue(self, col):#<br />
return self.colLabels[col]<br />
def GetRowLabelValue(self, row):#<br />
return self.rowLabels[row]<br />
class TestFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, title=”Grid Table”,<br />
size=(500,200))<br />
442 / 565
grid = wx.grid.Grid(self)<br />
table = TestTable()<br />
grid.SetTable(table, True)<br />
app = wx.PySimpleApp()<br />
frame = TestFrame()<br />
frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
<br />
SetColumnLabelAlignment(horiz, vert)SetRowLabelAlignment(horiz, vert)<br />
horiz<br />
wx.ALIGN_LEFT, wx.ALIGN_CENTREwx.ALIGN_RIGHTvert<br />
wx.ALIGN_TOP, wx.ALIGN_CENTRE,<br />
wx.ALIGN_BOTTOM<br />
<br />
SetLabelBackgroundColour(colour)<br />
, SetLabelFont(font), and SetLabelTextColour(colour)<br />
colourwx.Colour<strong>wxPython</strong><br />
fontwx.Fontset*get*<br />
GetLabelBackgoundColour(), GetLabelFont()GetLabelTextFont()<br />
14.2.3 <br />
<br />
14.4<br />
<br />
14.5<br />
443 / 565
14.4<br />
14.5 <br />
import wx<br />
import wx.grid<br />
class TestFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, title=”Grid Sizes”,<br />
size=(600,300))<br />
grid = wx.grid.Grid(self)<br />
grid.CreateGrid(5,5)<br />
for row <strong>in</strong> range(5):<br />
for col <strong>in</strong> range(5):<br />
grid.SetCellValue(row, col, ”(%s,%s)” % (row, col))<br />
grid.SetCellSize(2, 2, 2, 3)<br />
grid.SetColSize(1, 125)<br />
grid.SetRowSize(1, 100)<br />
app = wx.PySimpleApp()<br />
frame = TestFrame()<br />
frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
444 / 565
HTML<br />
rowspancolspan<strong>wxPython</strong><br />
SetCellSize(row, col, num_rows, num_cols)row,col<br />
num_rowsnum_cols<br />
num_rows, num_cols1<br />
num_rows, num_cols0<br />
<br />
<br />
SetCellOverflow(row, col, allow)<br />
passSetCellSize()<br />
<br />
<br />
SetColSize(col, width)SetRowSize(row, height)<br />
GetColSize(col)GetRowSize(row)<br />
<br />
<br />
<br />
<br />
SetDefaultColSize(width, resizeExist<strong>in</strong>gCols=False)<br />
SetDefaultRowSize(height, resizeExist<strong>in</strong>gRows=False)<br />
<br />
True<br />
False<br />
CreateGrid()SetTable()<br />
GetDefaultColSize()GetDefaultRowSize()<br />
<br />
<br />
<strong>wxPython</strong><br />
<strong>wxPython</strong><br />
<br />
<br />
445 / 565
<strong>wxPython</strong><br />
<br />
SetColM<strong>in</strong>imalAcceptableWidth(width)<br />
SetRowM<strong>in</strong>imalAcceptableHeight(height)<br />
<br />
SetColM<strong>in</strong>imalWidth(col, width)SetRowM<strong>in</strong>imalHeight(row, height)<br />
<br />
<br />
set*get*<br />
* GetColM<strong>in</strong>imalAcceptableWidth()<br />
* GetRowM<strong>in</strong>imalAcceptableHeight()<br />
* GetColM<strong>in</strong>imalWidth(col)<br />
* GetRowM<strong>in</strong>imalHeight(row)<br />
<br />
<br />
<br />
set*SetRowLabelSize(width)<br />
SetColLabelSize(height)<br />
GetRowLabelSize()GetColLabelSize()<br />
<br />
<strong>wxPython</strong>AutoSize()<br />
<br />
AutoSizeColumn(col, setAsM<strong>in</strong>=True)<br />
AutoSizeRow(row, setAsM<strong>in</strong>=True)<br />
setAsM<strong>in</strong>True<br />
AutoSizeColumns(setAsM<strong>in</strong>=True)AutoSizeRows(setAsM<strong>in</strong>=True)<br />
<br />
<br />
<br />
* EnableDragColSize(enable=True)<br />
<br />
446 / 565
* EnableDragRowSize(enable=True)<br />
<br />
* EnableDragGridSize(enable=True)<br />
<br />
<br />
* DisableDragColSize()<br />
* DisableDragRowSize()<br />
* DisableDragGridSize()<br />
<br />
* CanDragColSize()<br />
* CanDragRowSize()<br />
* CanDragGridSize()<br />
14.2.4 <br />
<strong>wxPython</strong><br />
<br />
0<br />
* <br />
* <br />
* <br />
* <br />
<br />
<br />
IsSelection()TrueIsInSelection(row, col)<br />
<br />
True<br />
14.2<br />
447 / 565
14.2 <br />
GetSelectedCells()Python<br />
(row, col)<br />
GetSelectedCols()<br />
Python<br />
GetSelectedRows()<br />
Python<br />
GetSelectionBlockTopLeft()<br />
Python(row, col)(row, col)<br />
<br />
GetSelectionBlockBottomRight()<br />
Python(row, col)(row, col)<br />
<br />
<br />
ClearSelection()IsSelection()<br />
FalseSelectAll()<br />
SelectCol(col, addToSelected=False)<br />
SelectRow(row, addToSelected=False)<br />
addToSelectedTrue<br />
<br />
addToSelectedFalse<br />
<br />
SelectBlock(topRow, leftCol, bottomRow, rightCol, addToSelected=False)<br />
addToSelected<br />
<br />
IsVisible(row, col, wholeCellVisible=True)<br />
<br />
True<br />
wholeCellVisibleTrue<br />
TruewholeCellVisibleFalse<br />
TrueMakeCellVisible(row, col)<br />
<br />
448 / 565
GetGridCursorCol()GetGridCursorRow()<br />
<br />
SetGridCursor(row, col)<br />
MakeCellVisible<br />
14.3<br />
14.3 <br />
BlockToDeviceRect(topLeft, bottomRight)topLeft, bottomRight<br />
(row, col)wx.Rectwx.Rect<br />
<br />
CellToRect(row, col)wx.Rectwx.Rect(row, col)<br />
<br />
XToCol(x)x<br />
wx.NOT_FOUND<br />
XToEdgeOfCol(x)x<br />
wx.NOT_FOUND<br />
YToRow(y)y<br />
wx.NOT_FOUND<br />
YToEdgeOfRow(y)y<br />
wx.NOT_FOUND<br />
<br />
14.2.5 <br />
<br />
14.514.614.5<br />
wx.grid.GridCellAttr<br />
<br />
449 / 565
14.5<br />
14.6 <br />
import wx<br />
import wx.grid<br />
class TestFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, title=”Grid Attributes”,<br />
size=(600,300))<br />
grid = wx.grid.Grid(self)<br />
grid.CreateGrid(10,6)<br />
for row <strong>in</strong> range(10):<br />
for col <strong>in</strong> range(6):<br />
grid.SetCellValue(row, col, ”(%s,%s)” % (row, col))<br />
grid.SetCellTextColour(1, 1, ”red”)<br />
grid.SetCellFont(1,1, wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD))<br />
grid.SetCellBackgroundColour(2, 2, ”light blue”)<br />
attr = wx.grid.GridCellAttr()<br />
attr.SetTextColour(“navyblue”)<br />
attr.SetBackgroundColour(“p<strong>in</strong>k”)<br />
attr.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD))<br />
grid.SetAttr(4, 0, attr)<br />
450 / 565
grid.SetAttr(5, 1, attr)<br />
grid.SetRowAttr(8, attr)<br />
app = wx.PySimpleApp()<br />
frame = TestFrame()<br />
frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
<br />
SetDefaultCellAlignment(horiz, vert)<br />
horizwx.LEFTwx.CENTREwx.RIGHTvert<br />
wx.TOP, wx.CENTRE, wx.BOTTOMGetDefaultCellAlignment()<br />
(horiz, vert)<br />
SetDefaultCellTextColour(colour)<br />
SetDefaultCellBackgroundColour(colour)colour<br />
wx.Colourget*GetDefaultCellTextColour()<br />
GetDefaultCellBackgroundColour()SetDefaultCellFont(font)<br />
GetDefaultCellFont()<br />
<br />
GetCellAlignment(row, col)<br />
SetCellAlignment(row, col, horiz, vert)<br />
GetCellBackgroundColour(row, col)<br />
SetCellBackgroundColour(row, col, colour)<br />
GetCellFont(row, col)<br />
SetCellFont(row, col, font)<br />
GetCellTextColour(row, col)<br />
SetCellTextColour(row, col, colour)<br />
SetSelectionBackground(colour)SetSelectionForeground(colour)<br />
get*<br />
GetSelectionBackground()GetSelectionForeground()<br />
451 / 565
SetMarg<strong>in</strong>s(extraWidth, extraHeight)<br />
<br />
wx.grid.Gridwx.grid.GridCellAttr<br />
wx.grid.GridCellAttrget*set*<br />
GetOrCreateCellAttr(row, col)<br />
attr<br />
<br />
<br />
wx.grid.GridCellAttr()<br />
SetColAttr(attr)<br />
SetRowAttr(attr)<br />
14.6<br />
GetAttr(row, col)<br />
wx.grid.GridCellAttr<br />
<br />
EnableGridL<strong>in</strong>es(enable)enableTrue<br />
False<br />
SetGridL<strong>in</strong>eColor(colour)<br />
14.3 <br />
<br />
<br />
<br />
14.3.1 <br />
<br />
<br />
<br />
<strong>wxPython</strong><br />
<strong>wxPython</strong><br />
<br />
452 / 565
wx.grid.GridCellRenderer<br />
wx.grid.GridCellRenderer<br />
14.4<br />
get*,set*<br />
14.4 <br />
wx.grid.GridCellAutoWrapStr<strong>in</strong>gRenderer<br />
<br />
wx.grid.GridCellBoolRenderer——<br />
TrueFalse<br />
wx.grid.GridCellDateTimeRenderer<br />
wx.grid.GridCellEnumRenderer<br />
wx.grid.GridCellFloatRenderer<br />
(width=-1, precision=-1)<br />
wx.grid.GridCellNumberRenderer<br />
wx.grid.GridCellStr<strong>in</strong>gRenderer<br />
<br />
GetCellRenderer(row, col)<br />
SetCellRenderer(row, col, renderer)<br />
renderer<br />
<br />
GridCellAttrGetDefaultRenderer<br />
SetDefaultRenderer(renderer)<br />
<br />
<br />
SetColFormatBool(col), SetColFormatNumber(col)<br />
SetColFormatFloat(col, width, precision)<br />
453 / 565
wx.grid.PyGridCellRenderer<br />
<br />
<br />
14.6<br />
14.6<br />
14.7<br />
14.714.6<br />
#-*- encod<strong>in</strong>g:UTF-8 -*-<br />
import wx<br />
import wx.grid<br />
import random<br />
class RandomBackgroundRenderer(wx.grid.PyGridCellRenderer):#<br />
def __<strong>in</strong>it__(self):<br />
wx.grid.PyGridCellRenderer.__<strong>in</strong>it__(self)<br />
def Draw(self, grid, attr, dc, rect, row, col, isSelected):#<br />
text = grid.GetCellValue(row, col)<br />
hAlign, vAlign = attr.GetAlignment()<br />
dc.SetFont( attr.GetFont() )<br />
if isSelected:<br />
454 / 565
g = grid.GetSelectionBackground()<br />
fg = grid.GetSelectionForeground()<br />
else:<br />
bg = random.choice([“p<strong>in</strong>k”, ”sky blue”, ”cyan”, ”yellow”, ”plum”])<br />
fg = attr.GetTextColour()<br />
dc.SetTextBackground(bg)<br />
dc.SetTextForeground(fg)<br />
dc.SetBrush(wx.Brush(bg, wx.SOLID))<br />
dc.SetPen(wx.TRANSPARENT_PEN)<br />
dc.DrawRectangleRect(rect)<br />
grid.DrawTextRectangle(dc, text, rect, hAlign, vAlign)<br />
def GetBestSize(self, grid, attr, dc, row, col):<br />
text = grid.GetCellValue(row, col)<br />
dc.SetFont(attr.GetFont())<br />
w, h = dc.GetTextExtent(text)<br />
return wx.Size(w, h)<br />
def Clone(self):<br />
return RandomBackgroundRenderer()<br />
class TestFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, title=”Grid Renderer”,<br />
size=(640,480))<br />
grid = wx.grid.Grid(self)<br />
grid.CreateGrid(50,50)<br />
# Set this custom renderer just for row 4<br />
attr = wx.grid.GridCellAttr()<br />
attr.SetRenderer(RandomBackgroundRenderer())<br />
grid.SetRowAttr(4, attr)#5<br />
for row <strong>in</strong> range(10):<br />
for col <strong>in</strong> range(10):<br />
grid.SetCellValue(row, col,<br />
”cell (%d,%d)” % (row, col))<br />
455 / 565
app = wx.PySimpleApp()<br />
frame = TestFrame()<br />
frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
<br />
Draw()<br />
GetBestSize()<br />
Clone()<br />
Draw(grid, attr, dc, rect, row, col, isSelected)<br />
gridattr<br />
dcrect<br />
row,col<br />
isSelectedTrue<br />
<br />
GetBestSize(grid, attr, dc, row, col)wx.Size<br />
Clone()wx.grid.GridCellRenderer<br />
<br />
14.3.2 <br />
<strong>wxPython</strong><br />
<br />
<br />
EnableEdit<strong>in</strong>g(enable)——<br />
enableFalse<br />
<br />
<br />
IsEditable()<br />
SetReadOnly(row, col, isReadOnly=True)<br />
isReadOnly=TrueFalse<br />
SetReadOnly()wx.grid.GridCellAttr<br />
GetCellAttr(row, col).SetReadOnly(isReadOnly)<br />
<br />
456 / 565
SetReadOnlySetRowAttr()SetColAttr()<br />
<br />
EnableCellEditControl(enable=True)<br />
DisableCellEditControl()<br />
EnableCellEditControl(False)Enable*<br />
disable*enable*<br />
CanEnableCellControl()true<br />
<br />
IsCellEditControlEnabled()true<br />
<br />
ShowCellEditControl()<br />
HideCellEditControl()IsCurrentCellReadOnly()<br />
SaveEditControlValue()<br />
<br />
<br />
<br />
<br />
GetCellEditor(row, col)<br />
wx.grid.GridCellEditor<br />
SetCellEditor(row, col, editor)editor<br />
wx.grid.GridCellEditorGetDefaultEditor()<br />
SetDefaultEditor(editor)<br />
wx.grid.GridCellAttr<br />
14.3.3 <br />
<strong>wxPython</strong><br />
<br />
<br />
<strong>wxPython</strong>wx.grid.GridCellEditor14.5<br />
<br />
<br />
457 / 565
14.5 wxPyhton<br />
wx.grid.GridCellAutoWrapStr<strong>in</strong>gEditor<br />
wx.grid.GridCellBooleanEditor<br />
——<br />
10on/off<br />
wx.grid.GridCellChoiceEditor<br />
(choices,allowOthers=False)choices<br />
allowOthersTrue<br />
<br />
wx.grid.GridCellEnumEditorwx.grid.GridCellChoiceEditor<br />
<br />
wx.grid.GridCellFloatEditor <br />
(width=-1precision=-1)<br />
<br />
wx.grid.GridCellNumberEditor<br />
(m<strong>in</strong>=-1, max=-1)m<strong>in</strong>max<br />
sp<strong>in</strong>ner<br />
<br />
wx.grid.GridCellTextEditor<br />
<br />
<br />
wx.grid.PyGridCellEditor<br />
14.6<br />
14.7<br />
<br />
14.6 PyGridCellEditor<br />
Beg<strong>in</strong>Edit(row, col, grid)row,colgrid<br />
<br />
<br />
Clone()<br />
458 / 565
Create(parent, id, evtHandler)parentid<br />
evtHandler<br />
EndEdit(row, col, grid)True<br />
<br />
Reset()<br />
<br />
14.7 PyGridCellEditor<br />
Destroy()<br />
IsAcceptedKey(evt)evtTrueF2<br />
<br />
control,alt,shift<br />
Pa<strong>in</strong>tBackground(rect, attr) rectwx.Rectattr<br />
wc.grid.GridCellAttr<br />
<br />
SetSize(rect)rectwx.Rect<br />
<br />
Show(show, attr)showattr<br />
<br />
Start<strong>in</strong>gClick()<br />
<br />
Start<strong>in</strong>gKey(evt)<br />
<br />
<br />
SetCellEditor<br />
14.8<br />
<br />
14.8 <br />
#-*- encod<strong>in</strong>g:UTF-8 -*-<br />
import wx<br />
import wx.grid<br />
import str<strong>in</strong>g<br />
459 / 565
class UpCaseCellEditor(wx.grid.PyGridCellEditor):#<br />
def __<strong>in</strong>it__(self):<br />
wx.grid.PyGridCellEditor.__<strong>in</strong>it__(self)<br />
def Create(self, parent, id, evtHandler):#<br />
”””<br />
Called to create the control, which must derive from wx.Control.<br />
*Must Override*<br />
”””<br />
self._tc = wx.TextCtrl(parent, id, ””)<br />
self._tc.SetInsertionPo<strong>in</strong>t(0)<br />
self.SetControl(self._tc)<br />
if evtHandler:<br />
self._tc.PushEventHandler(evtHandler)<br />
self._tc.B<strong>in</strong>d(wx.EVT_CHAR, self.OnChar)<br />
def SetSize(self, rect):<br />
”””<br />
Called to position/size the edit control with<strong>in</strong> the cell rectangle.<br />
If you don’t fill the cell (the rect) then be sure to override<br />
Pa<strong>in</strong>tBackground and do someth<strong>in</strong>g mean<strong>in</strong>gful there.<br />
”””<br />
self._tc.SetDimensions(rect.x, rect.y, rect.width+2, rect.height+2,<br />
wx.SIZE_ALLOW_MINUS_ONE)<br />
def Beg<strong>in</strong>Edit(self, row, col, grid):<br />
”””<br />
Fetch the value from the table and prepare the edit control<br />
to beg<strong>in</strong> edit<strong>in</strong>g. Set the focus to the edit control.<br />
*Must Override*<br />
”””<br />
self.startValue = grid.GetTable().GetValue(row, col)<br />
self._tc.SetValue(self.startValue)<br />
self._tc.SetInsertionPo<strong>in</strong>tEnd()<br />
self._tc.SetFocus()<br />
self._tc.SetSelection(0, self._tc.GetLastPosition())<br />
460 / 565
def EndEdit(self, row, col, grid):<br />
”””<br />
Complete the edit<strong>in</strong>g of the current cell. Returns True if the value<br />
has changed. If necessary, the control may be destroyed.<br />
*Must Override*<br />
”””<br />
changed = False<br />
val = self._tc.GetValue()<br />
if val != self.startValue:<br />
changed = True<br />
grid.GetTable().SetValue(row, col, val) # update the table<br />
self.startValue = ’’<br />
self._tc.SetValue(‘’)<br />
return changed<br />
def Reset(self):<br />
”””<br />
Reset the value <strong>in</strong> the control back to its start<strong>in</strong>g value.<br />
*Must Override*<br />
”””<br />
self._tc.SetValue(self.startValue)<br />
self._tc.SetInsertionPo<strong>in</strong>tEnd()<br />
def Clone(self):<br />
”””<br />
Create a new object which is the copy of this one<br />
*Must Override*<br />
”””<br />
return UpCaseCellEditor()<br />
def Start<strong>in</strong>gKey(self, evt):<br />
”””<br />
If the editor is enabled by press<strong>in</strong>g keys on the grid, this will be<br />
called to let the editor do someth<strong>in</strong>g about that first key if desired.<br />
”””<br />
self.OnChar(evt)<br />
if evt.GetSkipped():<br />
461 / 565
self._tc.EmulateKeyPress(evt)<br />
def OnChar(self, evt):<br />
key = evt.GetKeyCode()<br />
if key > 255:<br />
evt.Skip()<br />
return<br />
char = chr(key)<br />
if char <strong>in</strong> str<strong>in</strong>g.letters:<br />
char = char.upper()<br />
self._tc.WriteText(char)#<br />
else:<br />
evt.Skip()<br />
class TestFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, title=”Grid Editor”,<br />
size=(640,480))<br />
grid = wx.grid.Grid(self)<br />
grid.CreateGrid(50,50)<br />
grid.SetDefaultEditor(UpCaseCellEditor())#<br />
app = wx.PySimpleApp()<br />
frame = TestFrame()<br />
frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
14.4 <br />
<br />
14.4.1 <br />
<br />
wx.grid.GridEvent<br />
wx.CommandEvent<br />
14.8<br />
462 / 565
14.8 wx.grid.GridEvent<br />
AltDown()altTrue<br />
ControlDown()controlTrue<br />
GetCol()<br />
GetPosition()wx.Po<strong>in</strong>t<br />
<br />
GetRow()<br />
MetaDown()metTrue<br />
Select<strong>in</strong>g()True<br />
False<br />
ShiftDown()shiftTrue<br />
wx.grid.GridEvent14.9<br />
14.9 <br />
wx.grid.EVT_GRID_CELL_CHANGE<br />
<br />
wx.grid.EVT_GRID_CELL_LEFT_CLICK<br />
<br />
wx.grid.EVT_GRID_CELL_LEFT_DCLICK<br />
<br />
wx.grid.EVT_GRID_CELL_RIGHT_CLICK<br />
<br />
wx.grid.EVT_GRID_CELL_RIGHT_DCLICK<br />
<br />
wx.grid.EVT_GRID_EDITOR_HIDDEN<br />
<br />
463 / 565
wx.grid.EVT_GRID_EDITOR_SHOWN<br />
<br />
wx.grid.EVT_GRID_LABEL_LEFT_CLICK<br />
<br />
wx.grid.EVT_GRID_LABEL_LEFT_DCLICK<br />
<br />
wx.grid.EVT_GRID_LABEL_RIGHT_CLICK<br />
<br />
wx.grid.EVT_GRID_LABEL_RIGHT_DCLICK<br />
<br />
wx.grid.EVT_GRID_Select_CELL<br />
<br />
wx.grid.GridSizeEvent<br />
wx.grid.EVT_GRID_COL_SIZE<br />
wx.grid.EVT_GRID_ROW_SIZE<br />
5wx.GridEvent!<br />
AltDown(), ControlDown(), GetPosition(), MetaDow(), ShiftDown<br />
wx.grid.GridSizeEventGetRowOrCol()<br />
<br />
wx.grid.EVT_GRID_RANGE_Select<br />
wx.grid.GridRangeSelectEvent<br />
<br />
GetBottomRightCoords(), GetBottomRow(), GetLeftCol(), GetRightCol(), GetTop<br />
RightCoords()GetTopRow()(row, col)<br />
<br />
EVT_GRID_EDITOR_CreateD<br />
wx.grid.GridEditorCreatedEvent<br />
GetCol(), GetRow(), GetControl()<br />
<br />
464 / 565
14.4.2 <br />
<br />
14.10<br />
expandSelectionexpandSelection<br />
True<br />
False<br />
14.10 <br />
MoveCursorDown(expandSelection)expandSelection<br />
False""True"shift-"<br />
MoveCursorDownBlock(expandSelection)expandSelection<br />
False"ctrl-"True"shift-ctrl-"<br />
MoveCursorLeft(expandSelection)expandSelectionFalse<br />
""True"shift-"<br />
MoveCursorLeftBlock(expandSelection)expandSelection<br />
False"ctrl-"True"shift-ctrl-"<br />
MoveCursorRight(expandSelection)expandSelection<br />
False""True"shift-"<br />
MoveCursorRightBlock(expandSelection)expandSelection<br />
False"ctrl-"True"shift-ctrl-"<br />
MoveCursorUp(expandSelection)expandSelectionFalse<br />
""True"shift-"<br />
MoveCursorUpBlock(expandSelection)expandSelection<br />
False"ctrl-"True"shift-ctrl-"<br />
MovePageDown()<br />
MovePageUp()<br />
<br />
<br />
465 / 565
14.5 <br />
1<br />
wx.grid.Grid<br />
__<strong>in</strong>it__<br />
<br />
2<br />
CreateGrid(numRows, numCols)<br />
SetCellValue(row, col, s)<br />
<br />
wx.grid.PyGridTableBase<br />
wx.grid.PyGridTableBaseGetValue(row, col)<br />
<br />
SetTable(table)<br />
<br />
3<br />
<br />
<br />
<br />
<br />
SetCellSize(row, col, numrows, numcols)<br />
<br />
4<br />
select*<br />
MakeCellVisible(row, col)<br />
<br />
5<br />
<br />
<br />
wx.Grid.PyGridCellRenderer<br />
<br />
6<br />
<br />
<br />
466 / 565
wx.grid.GridCellEditor<br />
7<br />
<br />
<br />
467 / 565
15 (tree control)<br />
<br />
* <br />
* <br />
* <br />
* <br />
* <br />
<br />
<br />
<br />
<br />
HTMLXML<br />
(DOM)<br />
<br />
<br />
<br />
15.1 <br />
wx.TreeCtrl15.1<br />
468 / 565
15.1<br />
15.115.1<br />
<br />
data.py<br />
15.1 <br />
import wx<br />
import data<br />
class TestFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, title=”simple tree”, size=(400,500))<br />
# Create the tree<br />
self.tree = wx.TreeCtrl(self)<br />
# Add a root node<br />
root = self.tree.AddRoot(“wx.Object”)<br />
469 / 565
# Add nodes from our data set<br />
self.AddTreeNodes(root, data.tree)<br />
e)<br />
ee)<br />
# B<strong>in</strong>d some <strong>in</strong>terest<strong>in</strong>g events<br />
self.B<strong>in</strong>d(wx.EVT_TREE_ITEM_EXPANDED, self.OnItemExpanded, self.tre<br />
self.B<strong>in</strong>d(wx.EVT_TREE_ITEM_COLLAPSED, self.OnItemCollapsed, self.tr<br />
self.B<strong>in</strong>d(wx.EVT_TREE_SEL_CHANGED, self.OnSelChanged, self.tree)<br />
self.B<strong>in</strong>d(wx.EVT_TREE_ITEM_ACTIVATED, self.OnActivated, self.tree)<br />
# Expand the first level<br />
self.tree.Expand(root)<br />
def AddTreeNodes(self, parentItem, items):<br />
”””<br />
Recursively traverses the data structure, add<strong>in</strong>g tree nodes to<br />
match it.<br />
”””<br />
for item <strong>in</strong> items:<br />
if type(item) == str:<br />
self.tree.AppendItem(parentItem, item)<br />
else:<br />
newItem = self.tree.AppendItem(parentItem, item[0])<br />
self.AddTreeNodes(newItem, item[1])<br />
def GetItemText(self, item):<br />
if item:<br />
return self.tree.GetItemText(item)<br />
else:<br />
return ””<br />
def OnItemExpanded(self, evt):<br />
pr<strong>in</strong>t ”OnItemExpanded: ”, self.GetItemText(evt.GetItem())<br />
def OnItemCollapsed(self, evt):<br />
pr<strong>in</strong>t ”OnItemCollapsed:”, self.GetItemText(evt.GetItem())<br />
470 / 565
def OnSelChanged(self, evt):<br />
pr<strong>in</strong>t ”OnSelChanged: ”, self.GetItemText(evt.GetItem())<br />
def OnActivated(self, evt):<br />
pr<strong>in</strong>t ”OnActivated: ”, self.GetItemText(evt.GetItem())<br />
app = wx.PySimpleApp(redirect=True)<br />
frame = TestFrame()<br />
frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
wx.TreeCtrl<strong>wxPython</strong><br />
wx.TreeControl(parent, id=-1, pos=wx.DefaultPosition,<br />
size=wx.DefaultSize, style=wx.TR_HAS_BUTTONS,<br />
validator=wx.DefaultValidator, name=”treeCtrl”)<br />
wx.W<strong>in</strong>dow<br />
<br />
data.py<br />
# Some sample data for the treectrl samples<br />
tree = [<br />
”wx.AcceleratorTable”,<br />
”wx.BrushList”,<br />
”wx.BusyInfo”,<br />
”wx.Clipboard”,<br />
”wx.Colour”,<br />
”wx.ColourData”,<br />
”wx.ColourDatabase”,<br />
”wx.ContextHelp”,<br />
[“wx.DC”, [<br />
”wx.ClientDC”,<br />
[“wx.MemoryDC”, [<br />
”wx.lib.colourchooser.canvas.BitmapBuffer”,<br />
[“wx.BufferedDC”, [<br />
471 / 565
”wx.BufferedPa<strong>in</strong>tDC”, ]]]],<br />
”wx.MetaFileDC”,<br />
”wx.MirrorDC”,<br />
”wx.Pa<strong>in</strong>tDC”,<br />
”wx.PostScriptDC”,<br />
”wx.Pr<strong>in</strong>terDC”,<br />
”wx.ScreenDC”,<br />
”wx.W<strong>in</strong>dowDC”,]],<br />
”wx.DragImage”,<br />
”wx.Effects”,<br />
”wx.Encod<strong>in</strong>gConverter”,<br />
[“wx.Event”, [<br />
”wx.ActivateEvent”,<br />
”wx.CalculateLayoutEvent”,<br />
”wx.CloseEvent”,<br />
[“wx.CommandEvent”, [<br />
”wx.calendar.CalendarEvent”,<br />
”wx.ChildFocusEvent”,<br />
”wx.ContextMenuEvent”,<br />
”wx.gizmos.DynamicSashSplitEvent”,<br />
”wx.gizmos.DynamicSashUnifyEvent”,<br />
”wx.F<strong>in</strong>dDialogEvent”,<br />
”wx.grid.GridEditorCreatedEvent”,<br />
”wx.HelpEvent”,<br />
[“wx.NotifyEvent”,[<br />
[“wx.BookCtrlEvent”, [<br />
”wx.ListbookEvent”,<br />
”wx.NotebookEvent ”,]],<br />
”wx.grid.GridEvent”,<br />
”wx.grid.GridRangeSelectEvent”,<br />
”wx.grid.GridSizeEvent”,<br />
”wx.ListEvent”,<br />
”wx.Sp<strong>in</strong>Event”,<br />
”wx.SplitterEvent”,<br />
”wx.TreeEvent”,<br />
”wx.wizard.WizardEvent ”,]],<br />
[“wx.PyCommandEvent”, [<br />
”wx.lib.colourselect.ColourSelectEvent”,<br />
”wx.lib.buttons.GenButtonEvent”,<br />
472 / 565
”wx.lib.gridmovers.GridColMoveEvent”,<br />
”wx.lib.gridmovers.GridRowMoveEvent”,<br />
”wx.lib.<strong>in</strong>tctrl.IntUpdatedEvent”,<br />
”wx.lib.masked.combobox.MaskedComboBoxSelectEvent”,<br />
”wx.lib.masked.numctrl.NumberUpdatedEvent”,<br />
”wx.lib.masked.timectrl.TimeUpdatedEvent ”,]],<br />
”wx.SashEvent”,<br />
”wx.ScrollEvent”,<br />
”wx.stc.StyledTextEvent”,<br />
”wx.TextUrlEvent”,<br />
”wx.UpdateUIEvent”,<br />
”wx.W<strong>in</strong>dowCreateEvent”,<br />
”wx.W<strong>in</strong>dowDestroyEvent ”,]],<br />
”wx.DisplayChangedEvent”,<br />
”wx.DropFilesEvent”,<br />
”wx.EraseEvent”,<br />
”wx.FocusEvent”,<br />
”wx.IconizeEvent”,<br />
”wx.IdleEvent”,<br />
”wx.InitDialogEvent”,<br />
”wx.JoystickEvent”,<br />
”wx.KeyEvent”,<br />
”wx.MaximizeEvent”,<br />
”wx.MenuEvent”,<br />
”wx.MouseCaptureChangedEvent”,<br />
”wx.MouseEvent”,<br />
”wx.MoveEvent”,<br />
”wx.NavigationKeyEvent”,<br />
”wx.NcPa<strong>in</strong>tEvent”,<br />
”wx.Pa<strong>in</strong>tEvent”,<br />
”wx.PaletteChangedEvent”,<br />
”wx.ProcessEvent”,<br />
[“wx.PyEvent”, [<br />
”wx.lib.throbber.UpdateThrobberEvent ”,]],<br />
”wx.QueryLayoutInfoEvent”,<br />
”wx.QueryNewPaletteEvent”,<br />
”wx.ScrollW<strong>in</strong>Event”,<br />
”wx.SetCursorEvent”,<br />
”wx.ShowEvent”,<br />
”wx.SizeEvent”,<br />
473 / 565
”wx.SysColourChangedEvent”,<br />
”wx.TaskBarIconEvent”,<br />
”wx.TimerEvent ”,]],<br />
[“wx.EvtHandler”, [<br />
”wx.lib.gridmovers.GridColMover”,<br />
”wx.lib.gridmovers.GridRowMover”,<br />
”wx.html.HtmlHelpController”,<br />
”wx.Menu”,<br />
”wx.Process”,<br />
[“wx.PyApp”, [<br />
[“wx.App”, [<br />
”wx.py.PyAlaCarte.App”,<br />
”wx.py.PyAlaMode.App”,<br />
”wx.py.PyAlaModeTest.App”,<br />
”wx.py.PyCrust.App”,<br />
”wx.py.PyShell.App”,<br />
[“wx.py.fill<strong>in</strong>g.App”, [<br />
”wx.py.PyFill<strong>in</strong>g.App ”,]],<br />
[“wx.PySimpleApp”, [<br />
”wx.lib.masked.maskededit.test”,]],<br />
”wx.PyWidgetTester ”,]]]],<br />
”wx.TaskBarIcon”,<br />
[“wx.Timer”, [<br />
”wx.PyTimer ”,]],<br />
[“wx.Validator”, [<br />
[“wx.PyValidator”,[<br />
”wx.lib.<strong>in</strong>tctrl.IntValidator”,]]]],<br />
[“wx.W<strong>in</strong>dow”, [<br />
[“wx.lib.colourchooser.canvas.Canvas”, [<br />
”wx.lib.colourchooser.pycolourslider.PyColourSlider”,<br />
”wx.lib.colourchooser.pypalette.PyPalette”,]],<br />
”wx.lib.gridmovers.ColDragW<strong>in</strong>dow”,<br />
[“wx.Control”,[<br />
[“wx.BookCtrl”, [<br />
”wx.Listbook”,<br />
[“wx.Notebook”,[<br />
”wx.py.editor.EditorNotebook”,<br />
”wx.py.editor.EditorShellNotebook”,]] ]],<br />
[“wx.Button”, [<br />
474 / 565
[“wx.BitmapButton”,[<br />
”wx.lib.colourselect.ColourSelect”,<br />
”wx.ContextHelpButton”,<br />
”wx.lib.foldmenu.FoldOutMenu ”,]] ]],<br />
”wx.calendar.CalendarCtrl”,<br />
”wx.CheckBox”,<br />
[“wx.ComboBox”,[<br />
[“wx.lib.masked.combobox.BaseMaskedComboBox”, [<br />
”wx.lib.masked.combobox.ComboBox”,<br />
”wx.lib.masked.combobox.PreMaskedComboBox”,]] ]],<br />
[“wx.ControlWithItems”, [<br />
[“wx.Choice”,[<br />
”wx.DirFilterListCtrl ”,]],<br />
”wx.ListBox”,<br />
”wx.CheckListBox ”,]],<br />
”wx.Gauge”,<br />
”wx.GenericDirCtrl”,<br />
”wx.gizmos.LEDNumberCtrl”,<br />
[“wx.ListCtrl”,[<br />
”wx.ListView ”,]],<br />
[“wx.PyControl”,[<br />
”wx.lib.calendar.Calendar”,<br />
[“wx.lib.buttons.GenButton”,[<br />
[“wx.lib.buttons.GenBitmapButton”,[<br />
[“wx.lib.buttons.GenBitmapTextButton”,[<br />
”wx.lib.buttons.GenBitmapTextToggleButton<br />
“,]],<br />
”wx.lib.buttons.GenBitmapToggleButton ”,]],<br />
”wx.lib.buttons.GenToggleButton ”,]],<br />
”wx.lib.statbmp.GenStaticBitmap”,<br />
”wx.lib.stattext.GenStaticText”,<br />
”wx.lib.popupctl.PopButton”,<br />
”wx.lib.popupctl.PopupControl”,<br />
”wx.lib.ticker.Ticker ”,]],<br />
”wx.RadioBox”,<br />
”wx.RadioButton”,<br />
”wx.ScrollBar”,<br />
”wx.Slider”,<br />
”wx.Sp<strong>in</strong>Button”,<br />
475 / 565
”wx.Sp<strong>in</strong>Ctrl”,<br />
[“wx.StaticBitmap”,[<br />
”wx.lib.fancytext.StaticFancyText ”,]],<br />
”wx.StaticBox”,<br />
”wx.StaticL<strong>in</strong>e”,<br />
”wx.StaticText”,<br />
[“wx.stc.StyledTextCtrl”,[<br />
[“wx.py.editw<strong>in</strong>dow.EditW<strong>in</strong>dow”,[<br />
”wx.py.crust.Display”,<br />
”wx.py.editor.EditW<strong>in</strong>dow”,<br />
”wx.py.fill<strong>in</strong>g.Fill<strong>in</strong>gText”,<br />
”wx.py.shell.Shell”,]],<br />
”wx.lib.pyshell.PyShellW<strong>in</strong>dow ”,]],<br />
[“wx.TextCtrl”, [<br />
[“wx.lib.masked.textctrl.BaseMaskedTextCtrl”,[<br />
”wx.lib.masked.ipaddrctrl.IpAddrCtrl”,<br />
”wx.lib.masked.numctrl.NumCtrl”,<br />
”wx.lib.masked.textctrl.PreMaskedTextCtrl”,<br />
”wx.lib.masked.textctrl.TextCtrl”,<br />
”wx.lib.masked.timectrl.TimeCtrl ”,]],<br />
”wx.py.crust.Calltip”,<br />
”wx.lib.sheet.CTextCellEditor”,<br />
”wx.py.crust.DispatcherList<strong>in</strong>g”,<br />
”wx.lib.<strong>in</strong>tctrl.IntCtrl”,<br />
”wx.lib.rightalign.RightTextCtrl”,<br />
”wx.py.crust.SessionList<strong>in</strong>g”,]],<br />
”wx.ToggleButton”,<br />
”wx.ToolBar”,<br />
[“wx.TreeCtrl”,[<br />
”wx.py.fill<strong>in</strong>g.Fill<strong>in</strong>gTree”,<br />
”wx.gizmos.RemotelyScrolledTreeCtrl ”,]],<br />
”wx.gizmos.TreeListCtrl ”,]],<br />
”wx.gizmos.DynamicSashW<strong>in</strong>dow”,<br />
”wx.lib.multisash.EmptyChild”,<br />
”wx.glcanvas.GLCanvas”,<br />
”wx.lib.imagebrowser.ImageView”,<br />
”wx.MDIClientW<strong>in</strong>dow”,<br />
”wx.MenuBar”,<br />
”wx.lib.multisash.MultiClient”,<br />
”wx.lib.multisash.MultiCloser”,<br />
476 / 565
”wx.lib.multisash.MultiCreator”,<br />
”wx.lib.multisash.MultiSash”,<br />
”wx.lib.multisash.MultiSizer”,<br />
”wx.lib.multisash.MultiSplit”,<br />
”wx.lib.multisash.MultiViewLeaf”,<br />
[“wx.Panel”,[<br />
”wx.gizmos.EditableListBox”,<br />
[“wx.lib.filebrowsebutton.FileBrowseButton”,[<br />
”wx.lib.filebrowsebutton.DirBrowseButton”,<br />
”wx.lib.filebrowsebutton.FileBrowseButtonWithHistory”,]],<br />
”wx.lib.floatcanvas.FloatCanvas.FloatCanvas”,<br />
”wx.lib.floatcanvas.NavCanvas.NavCanvas”,<br />
”wx.NotebookPage”,<br />
[“wx.PreviewControlBar”,[<br />
”wx.PyPreviewControlBar ”,]],<br />
”wx.lib.colourchooser.pycolourbox.PyColourBox”,<br />
”wx.lib.colourchooser.pycolourchooser.PyColourChooser”,<br />
[“wx.PyPanel”,[<br />
”wx.lib.throbber.Throbber”,]],<br />
”wx.lib.shell.PyShell”,<br />
”wx.lib.shell.PyShellInput”,<br />
”wx.lib.shell.PyShellOutput”,<br />
[“wx.ScrolledW<strong>in</strong>dow”,[<br />
”wx.lib.editor.editor.Editor”,<br />
[“wx.grid.Grid”,[<br />
”wx.lib.sheet.CSheet ”,]],<br />
[“wx.html.HtmlW<strong>in</strong>dow”,[<br />
”wx.lib.ClickableHtmlW<strong>in</strong>dow.PyClickableHtmlW<strong>in</strong>dow”,]],<br />
”wx.PreviewCanvas”,<br />
”wx.lib.pr<strong>in</strong>tout.Pr<strong>in</strong>tTableDraw”,<br />
[“wx.PyScrolledW<strong>in</strong>dow”,[<br />
”wx.lib.scrolledpanel.ScrolledPanel”,]],<br />
”wx.lib.ogl.ShapeCanvas”,<br />
”wx.gizmos.SplitterScrolledW<strong>in</strong>dow ”,]],<br />
[“wx.VScrolledW<strong>in</strong>dow”,[<br />
[“wx.VListBox”, [<br />
”wx.HtmlListBox ”,]] ]],<br />
[“wx.wizard.WizardPage”, [<br />
”wx.wizard.PyWizardPage”,<br />
”wx.wizard.WizardPageSimple ”,]],<br />
477 / 565
”wx.lib.plot.PlotCanvas”,<br />
”wx.lib.wxPlotCanvas.PlotCanvas”,<br />
[“wx.PopupW<strong>in</strong>dow”,[<br />
”wx.lib.foldmenu.FoldOutW<strong>in</strong>dow”,<br />
[“wx.PopupTransientW<strong>in</strong>dow”,[<br />
”wx.TipW<strong>in</strong>dow ”,]] ]],<br />
[“wx.PyW<strong>in</strong>dow”, [<br />
”wx.lib.analogclock.AnalogClockW<strong>in</strong>dow”,]],<br />
”wx.lib.gridmovers.RowDragW<strong>in</strong>dow”,<br />
[“wx.SashW<strong>in</strong>dow”,[<br />
”wx.SashLayoutW<strong>in</strong>dow ”,]],<br />
”wx.SplashScreenW<strong>in</strong>dow”,<br />
[“wx.SplitterW<strong>in</strong>dow”,[<br />
”wx.py.crust.Crust”,<br />
”wx.py.fill<strong>in</strong>g.Fill<strong>in</strong>g”,<br />
”wx.gizmos.Th<strong>in</strong>SplitterW<strong>in</strong>dow ”,]],<br />
”wx.StatusBar”,<br />
[“wx.TopLevelW<strong>in</strong>dow”,[<br />
[“wx.Dialog”,[<br />
”wx.lib.calendar.CalenDlg”,<br />
”wx.ColourDialog”,<br />
”wx.DirDialog”,<br />
”wx.FileDialog”,<br />
”wx.F<strong>in</strong>dReplaceDialog”,<br />
”wx.FontDialog”,<br />
”wx.lib.imagebrowser.ImageDialog”,<br />
”wx.MessageDialog”,<br />
”wx.MultiChoiceDialog”,<br />
”wx.lib.dialogs.MultipleChoiceDialog”,<br />
”wx.PageSetupDialog”,<br />
”wx.lib.popupctl.PopupDialog”,<br />
”wx.Pr<strong>in</strong>tDialog”,<br />
”wx.lib.dialogs.ScrolledMessageDialog”,<br />
”wx.S<strong>in</strong>gleChoiceDialog”,<br />
”wx.TextEntryDialog”,<br />
”wx.wizard.Wizard ”,]],<br />
[“wx.Frame”, [<br />
”wx.lib.analogclockopts.ACCustomizationFrame”,<br />
”wx.py.fill<strong>in</strong>g.Fill<strong>in</strong>gFrame”,<br />
[“wx.py.frame.Frame”,[<br />
478 / 565
”wx.py.crust.CrustFrame”,<br />
[“wx.py.editor.EditorFrame”,[<br />
”wx.py.editor.EditorNotebookFrame”,]],<br />
”wx.py.shell.ShellFrame”,]],<br />
”wx.html.HtmlHelpFrame”,<br />
”wx.MDIChildFrame”,<br />
”wx.MDIParentFrame”,<br />
”wx.M<strong>in</strong>iFrame”,<br />
[“wx.PreviewFrame”,[<br />
”wx.PyPreviewFrame ”,]],<br />
”wx.ProgressDialog”,<br />
”wx.SplashScreen”,<br />
”wx.lib.splashscreen.SplashScreen”,<br />
”wx.lib.masked.maskededit.test2”,<br />
”wx.lib.plot.TestFrame ”,]] ]],<br />
”wx.gizmos.TreeCompanionW<strong>in</strong>dow ”,]] ]] ]],<br />
”wx.FileHistory”,<br />
”wx.FileSystem”,<br />
”wx.F<strong>in</strong>dReplaceData”,<br />
”wx.FontData”,<br />
”wx.FontList”,<br />
”wx.FSFile”,<br />
[“wx.GDIObject”,[<br />
”wx.Bitmap”,<br />
”wx.Brush”,<br />
”wx.Cursor”,<br />
”wx.Font”,<br />
”wx.Icon”,<br />
”wx.Palette”,<br />
”wx.Pen”,<br />
”wx.Region ”,]],<br />
”wx.glcanvas.GLContext”,<br />
[“wx.grid.GridTableBase”, [<br />
”wx.grid.GridStr<strong>in</strong>gTable”,<br />
”wx.grid.PyGridTableBase ”,]],<br />
[“wx.html.HtmlCell”, [<br />
”wx.html.HtmlColourCell”,<br />
”wx.html.HtmlConta<strong>in</strong>erCell”,<br />
”wx.html.HtmlFontCell”,<br />
”wx.html.HtmlWidgetCell”,<br />
479 / 565
”wx.html.HtmlWordCell ”,]],<br />
”wx.html.HtmlDCRenderer”,<br />
”wx.html.HtmlEasyPr<strong>in</strong>t<strong>in</strong>g”,<br />
”wx.html.HtmlFilter”,<br />
”wx.html.HtmlL<strong>in</strong>kInfo”,<br />
[“wx.html.HtmlParser”, [<br />
”wx.html.HtmlW<strong>in</strong>Parser ”,]],<br />
”wx.html.HtmlTag”,<br />
[“wx.html.HtmlTagHandler”, [<br />
[“wx.html.HtmlW<strong>in</strong>TagHandler”, [<br />
”wx.lib.wxpTag.wxpTagHandler ”,]] ]],<br />
”wx.Image”,<br />
[“wx.ImageHandler”, [<br />
[“wx.BMPHandler”, [<br />
[“wx.ICOHandler”, [<br />
[“wx.CURHandler”, [<br />
”wx.ANIHandler ”,]] ]] ]],<br />
”wx.GIFHandler”,<br />
”wx.JPEGHandler”,<br />
”wx.PCXHandler”,<br />
”wx.PNGHandler”,<br />
”wx.PNMHandler”,<br />
”wx.TIFFHandler”,<br />
”wx.XPMHandler ”,]],<br />
”wx.ImageList”,<br />
”wx.IndividualLayoutConstra<strong>in</strong>t”,<br />
”wx.LayoutAlgorithm”,<br />
[“wx.LayoutConstra<strong>in</strong>ts”, [<br />
”wx.lib.anchors.LayoutAnchors”,<br />
”wx.lib.layoutf.Layoutf”,]],<br />
”wx.ListItem”,<br />
”wx.Mask”,<br />
”wx.MenuItem”,<br />
”wx.MetaFile”,<br />
”wx.PageSetupDialogData”,<br />
”wx.PenList”,<br />
”wx.Pr<strong>in</strong>tData”,<br />
”wx.Pr<strong>in</strong>tDialogData”,<br />
”wx.Pr<strong>in</strong>ter”,<br />
[“wx.Pr<strong>in</strong>tout”, [<br />
480 / 565
]<br />
”wx.html.HtmlPr<strong>in</strong>tout”,<br />
”wx.lib.plot.PlotPr<strong>in</strong>tout”,<br />
”wx.lib.pr<strong>in</strong>tout.SetPr<strong>in</strong>tout ”,]],<br />
[“wx.Pr<strong>in</strong>tPreview”, [<br />
”wx.PyPr<strong>in</strong>tPreview ”,]],<br />
”wx.RegionIterator”,<br />
[“wx.Sizer”, [<br />
”wx.BookCtrlSizer”,<br />
[“wx.BoxSizer”, [<br />
”wx.StaticBoxSizer”, ]],<br />
[“wx.GridSizer”, [<br />
[“wx.FlexGridSizer”, [<br />
”wx.GridBagSizer”,]] ]],<br />
”wx.NotebookSizer”,<br />
”wx.PySizer”,]],<br />
[“wx.SizerItem”, [<br />
”wx.GBSizerItem”,]],<br />
”wx.SystemOptions”,<br />
”wx.ToolBarToolBase”,<br />
”wx.ToolTip”,<br />
”wx.gizmos.TreeListColumnInfo”,<br />
”wx.xrc.XmlDocument”,<br />
”wx.xrc.XmlResource”,<br />
”wx.xrc.XmlResourceHandler ”,<br />
15.1.1 root()<br />
root()<br />
<br />
AddRoot(text, image=-1, selImage=-1, data=None)<br />
<br />
<strong>wxPython</strong>text<br />
imagetext<br />
15.5<br />
data<br />
<br />
481 / 565
AddRoot()ID<br />
wx.TreeItemIdID<br />
wx.TreeItemId<br />
wx.TreeItemId——<br />
<br />
15.1.2 <br />
<br />
AppendItem(parent, text, image=-1, selImage=-1, data=None)parent<br />
wx.TreeItemIdtext<br />
imageselImageAddRoot()<br />
<br />
wx.TreeItemIdID<br />
<br />
rootId = tree.AddRoot(“The Root”)<br />
childId = tree.AppendItem(rootId, ”A Child”)<br />
grandChildId = tree.AppendItem(childId, ”A Grandchild”)<br />
root()<br />
<br />
<br />
PrependItem(parent, text, image=-1, selImage=-1, data=None)<br />
<br />
<br />
InsertItem(parent, previous, text,image=-1, selImage=-1, data=None)<br />
previouswx.TreeItemId<br />
<br />
InsertItemBefore(parent, before, text, image=-1, selImage=-1, data=None)<br />
beforebefore<br />
ID<br />
wx.TreeItemId<br />
15.1.3 <br />
Delete(item)item<br />
wx.TreeItemIdEVT_TREE_Delete_ITEM<br />
482 / 565
DeleteChildren(item)<br />
itemwx.TreeItemId<br />
DeleteAllItems()<br />
W<strong>in</strong>dows<br />
GetItemText(item)<br />
itemwx.TreeItemId<br />
SetItemText(item, text)item<br />
wx.TreeItemIdtext<br />
GetCount()<br />
<br />
GetChildrenCount(item, recursively=True)itemwx.TreeItemId<br />
recursivelyFalse<br />
True<br />
15.2 <br />
<br />
15.1<br />
15.1 <br />
wx.TR_HAS_BUTTONSW<strong>in</strong>dows+-<br />
<br />
wx.TR_NO_BUTTONS<br />
15.2<br />
15.2 <br />
wx.TR_LINES_AT_ROOTroot<br />
wx.TR_HIDE_ROOTroot<br />
wx.TR_NO_LINES<br />
wx.TR_LINES_AT_ROOT<br />
wx.TR_ROW_LINES <br />
483 / 565
15.3<br />
15.3 <br />
wx.TR_EXTENDED<br />
wx.TR_MULTIPLE<br />
wx.TR_SINGLE<br />
15.4<br />
15.4 <br />
wx.TR_FULL_ROW_HIGHLIGHT<br />
W<strong>in</strong>dows<br />
wx.NO_LINES<br />
wx.TR_HAS_VARIABLE_ROW_HEIGHT<br />
<br />
wx.TR_HIDE_ROOTAddRoot()root<br />
root<br />
root<br />
wx.TR_DEFAULT_STYLE<br />
SetW<strong>in</strong>dowStyle(styles)<br />
styles<br />
<br />
itemwx.TreeItemId<br />
SetItemBackgroundColor(item, col)col<br />
wx.Colour<br />
SetItemTextColour(item,col)<br />
SetItemFont(item, font)fontwx.Font<br />
<br />
SetItemBold(item, bold=True)bold<br />
set*get*<br />
GetItemBackgroundColor(item), GetItemTextColour(item), GetItemFont(item),<br />
IsBold(item)itemwx.TreeItemId<br />
484 / 565
15.3 <br />
SortChildren(item)<br />
itemwx.TreeItemId<br />
<br />
<br />
None<br />
<br />
15.1<br />
<br />
wx.TreeItemData<strong>wxPython</strong><br />
Python<br />
set*SetItemPyData(item, obj)item<br />
wx.TreeItemIdobjPython<strong>wxPython</strong><br />
GetItemPyData(item)<br />
Python<br />
wx.TreeItemData<br />
wx.TreeItemData(obj)objPython<br />
GetItemData(item)SetItemData(item, obj)Python<br />
SetItemPyData()<br />
SetItemPyData(item, obj)<br />
GetItemPyData(item)<br />
wx.TreeCtrl<br />
OnCompareItems(item1, item2)<br />
item1, item2wx.TreeItemIditem1item2<br />
-1item1item21<br />
0<br />
OnCompareItems()<br />
GetItemPyData()<br />
def OnCompareItems(self, item1, item2);<br />
data1 = self.GetItemPyData(item1)<br />
data2 = self.GetItemPyData(item2)<br />
return cmp(data1, data2)<br />
485 / 565
15.4 <br />
<br />
13<br />
SetImageList(imageList)AssignImageList(imageList)<br />
<br />
GetImageList()<br />
15.2<br />
15.2<br />
15.215.2ArtProvider<br />
15.2 <br />
#-*- encod<strong>in</strong>g:UTF-8 -*-<br />
import wx<br />
import data<br />
class TestFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
486 / 565
wx.Frame.__<strong>in</strong>it__(self, None,<br />
title=”simple tree with icons”, size=(400,500))<br />
# <br />
il = wx.ImageList(16,16)<br />
# <br />
self.fldridx = il.Add(<br />
wx.ArtProvider.GetBitmap(wx.ART_FOLDER,<br />
wx.ART_OTHER, (16,16)))<br />
self.fldropenidx = il.Add(<br />
wx.ArtProvider.GetBitmap(wx.ART_FILE_OPEN,<br />
wx.ART_OTHER, (16,16)))<br />
self.fileidx = il.Add(<br />
wx.ArtProvider.GetBitmap(wx.ART_NORMAL_FILE,<br />
wx.ART_OTHER, (16,16)))<br />
# <br />
self.tree = wx.TreeCtrl(self)<br />
# <br />
self.tree.AssignImageList(il)<br />
root = self.tree.AddRoot(“wx.Object”)<br />
self.tree.SetItemImage(root, self.fldridx,<br />
wx.TreeItemIcon_Normal)# <br />
self.tree.SetItemImage(root, self.fldropenidx,<br />
wx.TreeItemIcon_Expanded)<br />
self.AddTreeNodes(root, data.tree)<br />
self.tree.Expand(root)<br />
def AddTreeNodes(self, parentItem, items):<br />
for item <strong>in</strong> items:<br />
if type(item) == str:<br />
newItem = self.tree.AppendItem(parentItem, item)<br />
self.tree.SetItemImage(newItem, self.fileidx,<br />
wx.TreeItemIcon_Normal)# <br />
else:<br />
newItem = self.tree.AppendItem(parentItem, item[0])<br />
487 / 565
self.tree.SetItemImage(newItem, self.fldridx,<br />
wx.TreeItemIcon_Normal)# <br />
self.tree.SetItemImage(newItem, self.fldropenidx,<br />
wx.TreeItemIcon_Expanded)<br />
self.AddTreeNodes(newItem, item[1])<br />
def GetItemText(self, item):<br />
if item:<br />
return self.tree.GetItemText(item)<br />
else:<br />
return ””<br />
app = wx.PySimpleApp(redirect=True)<br />
frame = TestFrame()<br />
frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
<br />
<br />
<br />
GetItemImage(item, which=wx.TreeItemIcon_Normal)item<br />
wx.TreeItemIdwhich<br />
wx.TreeItemIcon_Normalwhich<br />
wx.TreeItemIcon_Selected<br />
wx.TreeItemIcon_ExpandedwxTreeItemIcon_SelectedExpanded<br />
<br />
——<br />
SetItemImage(item, image, which=wx.TreeItemIcon_Normal)<br />
itemwx.TreeItemIdimagewhichget*<br />
<br />
15.5 <br />
15.1Python<br />
<br />
<br />
488 / 565
GetRootItem()<br />
wx.TreeItemIdGetItemText()<br />
GetItemPyData()<br />
<br />
GetFirstChild(item)<br />
(child, cookie)itemwx.TreeItemId<br />
<br />
cookie<br />
<br />
GetFirstChild()cookie<br />
GetNextChild(item, cookie)itemIDcookie<br />
GetFirstChild()GetNextChild()GetNextChild()<br />
(child, cookie)<br />
ID<br />
wx.TreeItemId.IsOk()__nonzero__<br />
<br />
def getChildren(tree, parent):<br />
result = []<br />
item, cookie = tree.GetFirstChild(parent)<br />
while item:<br />
result.append(tree.GetItemText(item))<br />
item, cookie = tree.getNextChild(parent, cookie)<br />
return result<br />
<br />
<br />
result<br />
GetLastChild(item)<br />
wx.TreeItemId<br />
cookie<br />
GetItemParent(item)ID<br />
GetNextSibl<strong>in</strong>g(item)GetPrevSibl<strong>in</strong>g(item)<br />
wx.TreeItemId<br />
cookie<br />
489 / 565
item.IsOk() == False<br />
ItemHasChildren(item)<br />
TrueFalseSetItemHasChildren(item, hasChildren=True)<br />
<br />
<br />
15.7<br />
15.6 <br />
<br />
SelectItem(item,select=True) <br />
itemwx.TreeItemIdselect<br />
Falseitem<br />
SelectItem()item<br />
ToggleItemSelection(item)<br />
item<br />
Unselect()<br />
UnselectAll()<br />
<br />
UnselectItem(item)<br />
IsSelected(item)<br />
TrueFalseGetSelection()<br />
wx.TreeItemIdGetSelections()<br />
wx.TreeItemIdPython<br />
<br />
wx.EVT_TREE_SEL_CHANGING,<br />
Veto()<br />
wx.EVT_TREE_SEL_CHANGED<br />
wx.TreeEvent15.8<br />
15.7 <br />
<br />
Collapse(item)Expand(item)<br />
<br />
490 / 565
CollapseAndReset(item)<br />
Toggle(item)<br />
IsExpanded(item)<br />
<br />
<br />
wx.EVT_TREE_ITEM_COLLAPSING wx.EVT_TREE_ITEM_EXPANDING<br />
Veto()<br />
EVT_TREE_ITEM_COLLAPSED<br />
wx.EVT_TREE_ITEM_EXPANDEDwx.TreeEvent<br />
<br />
<br />
<br />
15.3<br />
15.3 <br />
#-*- encod<strong>in</strong>g:UTF-8 -*-<br />
import wx<br />
import data<br />
class TestFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, title=”virtual tree with icons”, size=(400,500))<br />
il = wx.ImageList(16,16)<br />
self.fldridx = il.Add(<br />
wx.ArtProvider.GetBitmap(wx.ART_FOLDER, wx.ART_OTHER, (16,16)))<br />
self.fldropenidx = il.Add(<br />
wx.ArtProvider.GetBitmap(wx.ART_FILE_OPEN, wx.ART_OTHER, (16,<br />
16)))<br />
self.fileidx = il.Add(<br />
wx.ArtProvider.GetBitmap(wx.ART_NORMAL_FILE, wx.ART_OTHER, (1<br />
6,16)))<br />
self.tree = wx.TreeCtrl(self)<br />
self.tree.AssignImageList(il)<br />
root = self.tree.AddRoot(“wx.Object”)<br />
self.tree.SetItemImage(root, self.fldridx,<br />
491 / 565
wx.TreeItemIcon_Normal)<br />
self.tree.SetItemImage(root, self.fldropenidx,<br />
wx.TreeItemIcon_Expanded)<br />
# Instead of add<strong>in</strong>g nodes for the whole tree, just attach some<br />
# data to the root node so that it can f<strong>in</strong>d and add its child<br />
# nodes when it is expanded, and mark it as hav<strong>in</strong>g children so<br />
# it will be expandable.<br />
self.tree.SetItemPyData(root, data.tree)#<br />
self.tree.SetItemHasChildren(root, True)<br />
# B<strong>in</strong>d some <strong>in</strong>terest<strong>in</strong>g events<br />
# <br />
self.B<strong>in</strong>d(wx.EVT_TREE_ITEM_EXPANDED, self.OnItemExpanded, self.tre<br />
e)<br />
self.B<strong>in</strong>d(wx.EVT_TREE_ITEM_COLLAPSED, self.OnItemCollapsed, self.tr<br />
ee)<br />
self.B<strong>in</strong>d(wx.EVT_TREE_SEL_CHANGED, self.OnSelChanged, self.tree)<br />
self.B<strong>in</strong>d(wx.EVT_TREE_ITEM_ACTIVATED, self.OnActivated, self.tree)<br />
ree)<br />
self.B<strong>in</strong>d(wx.EVT_TREE_ITEM_EXPANDING, self.OnItemExpand<strong>in</strong>g, self.t<br />
self.tree.Expand(root)<br />
def AddTreeNodes(self, parentItem):#<br />
”””<br />
Add nodes for just the children of the parentItem<br />
”””<br />
items = self.tree.GetItemPyData(parentItem)<br />
for item <strong>in</strong> items:<br />
if type(item) == str:<br />
# a leaf node<br />
newItem = self.tree.AppendItem(parentItem, item)<br />
self.tree.SetItemImage(newItem, self.fileidx,<br />
wx.TreeItemIcon_Normal)<br />
else:<br />
# this item has children<br />
newItem = self.tree.AppendItem(parentItem, item[0])<br />
self.tree.SetItemImage(newItem, self.fldridx,<br />
492 / 565
wx.TreeItemIcon_Normal)<br />
self.tree.SetItemImage(newItem, self.fldropenidx,<br />
wx.TreeItemIcon_Expanded)<br />
self.tree.SetItemPyData(newItem, item[1])<br />
self.tree.SetItemHasChildren(newItem, True)<br />
def GetItemText(self, item):<br />
if item:<br />
return self.tree.GetItemText(item)<br />
else:<br />
return ””<br />
def OnItemExpanded(self, evt):<br />
pr<strong>in</strong>t ”OnItemExpanded: ”, self.GetItemText(evt.GetItem())<br />
def OnItemExpand<strong>in</strong>g(self, evt):#<br />
# When the item is about to be expanded add the first level of child nodes<br />
pr<strong>in</strong>t ”OnItemExpand<strong>in</strong>g:”, self.GetItemText(evt.GetItem())<br />
self.AddTreeNodes(evt.GetItem())<br />
def OnItemCollapsed(self, evt):<br />
pr<strong>in</strong>t ”OnItemCollapsed:”, self.GetItemText(evt.GetItem())<br />
# And remove them when collapsed as we don’t need them any longer<br />
self.tree.DeleteChildren(evt.GetItem())#<br />
def OnSelChanged(self, evt):<br />
pr<strong>in</strong>t ”OnSelChanged: ”, self.GetItemText(evt.GetItem())<br />
def OnActivated(self, evt):<br />
pr<strong>in</strong>t ”OnActivated: ”, self.GetItemText(evt.GetItem())<br />
app = wx.PySimpleApp(redirect=True)<br />
frame = TestFrame()<br />
frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
493 / 565
IsVisible(item)<br />
TrueFalseEnsureVisible(item)<br />
<br />
<br />
ScrollTo(item)<br />
GetFirstVisibleItem()<br />
wx.TreeItemId<br />
GetNextVisible(item)itemGetFirstVisibleItem()<br />
GetNextVisible()<br />
GetPreviousVisible(item)item<br />
<br />
GetIndent()SetIndent(<strong>in</strong>dent)<br />
<strong>in</strong>dent<br />
HitTest(po<strong>in</strong>t)po<strong>in</strong>t<br />
wx.Po<strong>in</strong>t(item, flags)<br />
itemwx.TreeItemIdNone<br />
flags<br />
15.5flags<br />
<br />
GetBound<strong>in</strong>gRect(item, textOnly=False)wx.Rect<br />
itemwx.TreeItemId<br />
textOnlyTrue<br />
False<br />
item<br />
None<br />
494 / 565
15.5<br />
wx.TREE_HITTEST_ABOVE<br />
<br />
wx.TREE_HITTEST_BELOW<br />
<br />
wx.TREE_HITTEST_NOWhere<br />
<br />
wx.TREE_HITTEST_ONITEMBUTTON/<br />
<br />
wx.TREE_HITTEST_ONITEMICON<br />
wx.TREE_HITTEST_ONITEMINDENT<br />
<br />
wx.TREE_HITTEST_ONITEMLABEL<br />
wx.TREE_HITTEST_ONITEMRIGHT<br />
wx.TREE_HITTEST_ONITEMSTATEICON<br />
wx.TREE_HITTEST_TOLEFT<br />
<br />
wx.TREE_HITTEST_TORIGHT<br />
<br />
15.8 <br />
<br />
wx.TR_EDIT_LABELS<br />
<br />
esc<br />
<br />
EditLabel(item)item<br />
wx.TreeItemId<br />
EndEditLabel(cancelEdit)<br />
IDcancelEditTrue<br />
495 / 565
False<br />
GetEditControl()wx.TextCtrl<br />
NoneW<strong>in</strong>dows<br />
EditLabel()<br />
wx.EVT_TREE_BEGIN_LABEL_EDITwx.TreeEvent<br />
Veto()<br />
EndEditLabel()<br />
wx.EVT_TREE_END_LABEL_EDIT<br />
<br />
15.9 <br />
wx.TreeEvent15.6<br />
15.6 wx.TreeEvent<br />
GetKeyCode()wx.EVT_TREE_KEY_DOWN<br />
CTRL,SHIFT,and ALT<br />
<br />
GetItem()wx.TreeItemId<br />
GetKeyEvent()wx.EVT_TREE_KEY_DOWNwx.KeyEvent<br />
<br />
GetLabel()wx.EVT_TREE_BEGIN_LABEL_EDIT<br />
wx.EVT_TREE_END_LABEL_EDIT<br />
GetPo<strong>in</strong>t()wx.Po<strong>in</strong>t<br />
IsEditCancelled()wx.EVT_TREE_END_LABEL_EDIT<br />
TrueFalse<br />
SetToolTip(tooltip)wx.EVT_TREE_ITEM_GETTOOLTIP<br />
W<strong>in</strong>dows<br />
15.715.6wx.TreeEvent<br />
<br />
496 / 565
15.7 <br />
wx.EVT_TREE_BEGIN_DRAG<br />
<br />
Allow()<br />
wx.EVT_TREE_BEGIN_RDRAG<br />
<br />
Allow()<br />
wx.EVT_TREE_ITEM_ACTIVATED<br />
wx.EVT_TREE_ITEM_GETTOOLTIP<br />
<br />
<br />
wx.EVT_TREE_KEY_DOWN<br />
<br />
<br />
<br />
15.10 <br />
wx.TreeCtrl<strong>wxPython</strong>wx.gizmos.TreeListCtrl<br />
wx.TreeCtrl<br />
TreeListCtrl15.3<br />
<br />
497 / 565
15.3<br />
15.4<br />
15.4 <br />
import wx<br />
import wx.gizmos<br />
import data<br />
class TestFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, title=”TreeListCtrl”, size=(400,500))<br />
# Create an image list<br />
il = wx.ImageList(16,16)<br />
# Get some standard images from the art provider and add them<br />
# to the image list<br />
self.fldridx = il.Add(<br />
wx.ArtProvider.GetBitmap(wx.ART_FOLDER, wx.ART_OTHER, (16,16)))<br />
self.fldropenidx = il.Add(<br />
498 / 565
wx.ArtProvider.GetBitmap(wx.ART_FILE_OPEN, wx.ART_OTHER, (16,<br />
16)))<br />
self.fileidx = il.Add(<br />
wx.ArtProvider.GetBitmap(wx.ART_NORMAL_FILE, wx.ART_OTHER, (1<br />
6,16)))<br />
# Create the tree<br />
# <br />
self.tree = wx.gizmos.TreeListCtrl(self, style =<br />
wx.TR_DEFAULT_STYLE<br />
| wx.TR_FULL_ROW_HIGHLIGHT)<br />
# Give it the image list<br />
self.tree.AssignImageList(il)<br />
# create some columns<br />
#<br />
self.tree.AddColumn(“Class Name”)<br />
self.tree.AddColumn(“Description”)<br />
self.tree.SetMa<strong>in</strong>Column(0) # the one with the tree <strong>in</strong> it...<br />
self.tree.SetColumnWidth(0, 200)<br />
self.tree.SetColumnWidth(1, 200)<br />
# Add a root node and assign it some images<br />
root = self.tree.AddRoot(“wx.Object”)<br />
self.tree.SetItemText(root, ”A description of wx.Object”, 1)#<br />
self.tree.SetItemImage(root, self.fldridx,<br />
wx.TreeItemIcon_Normal)<br />
self.tree.SetItemImage(root, self.fldropenidx,<br />
wx.TreeItemIcon_Expanded)<br />
# Add nodes from our data set<br />
self.AddTreeNodes(root, data.tree)<br />
e)<br />
# B<strong>in</strong>d some <strong>in</strong>terest<strong>in</strong>g events<br />
self.B<strong>in</strong>d(wx.EVT_TREE_ITEM_EXPANDED, self.OnItemExpanded, self.tre<br />
499 / 565
ee)<br />
self.B<strong>in</strong>d(wx.EVT_TREE_ITEM_COLLAPSED, self.OnItemCollapsed, self.tr<br />
self.B<strong>in</strong>d(wx.EVT_TREE_SEL_CHANGED, self.OnSelChanged, self.tree)<br />
self.B<strong>in</strong>d(wx.EVT_TREE_ITEM_ACTIVATED, self.OnActivated, self.tree)<br />
# Expand the first level<br />
self.tree.Expand(root)<br />
def AddTreeNodes(self, parentItem, items):<br />
”””<br />
Recursively traverses the data structure, add<strong>in</strong>g tree nodes to<br />
match it.<br />
”””<br />
for item <strong>in</strong> items:<br />
if type(item) == str:<br />
newItem = self.tree.AppendItem(parentItem, item)<br />
self.tree.SetItemText(newItem, ”A description of %s” % item, 1)#<br />
<br />
self.tree.SetItemImage(newItem, self.fileidx,<br />
wx.TreeItemIcon_Normal)<br />
else:<br />
newItem = self.tree.AppendItem(parentItem, item[0])<br />
self.tree.SetItemText(newItem, ”A description of %s” % item[0], 1)<br />
self.tree.SetItemImage(newItem, self.fldridx,<br />
wx.TreeItemIcon_Normal)<br />
self.tree.SetItemImage(newItem, self.fldropenidx,<br />
wx.TreeItemIcon_Expanded)<br />
self.AddTreeNodes(newItem, item[1])<br />
def GetItemText(self, item):<br />
if item:<br />
return self.tree.GetItemText(item)<br />
else:<br />
return ””<br />
def OnItemExpanded(self, evt):<br />
pr<strong>in</strong>t ”OnItemExpanded: ”, self.GetItemText(evt.GetItem())<br />
500 / 565
def OnItemCollapsed(self, evt):<br />
pr<strong>in</strong>t ”OnItemCollapsed:”, self.GetItemText(evt.GetItem())<br />
def OnSelChanged(self, evt):<br />
pr<strong>in</strong>t ”OnSelChanged: ”, self.GetItemText(evt.GetItem())<br />
def OnActivated(self, evt):<br />
pr<strong>in</strong>t ”OnActivated: ”, self.GetItemText(evt.GetItem())<br />
app = wx.PySimpleApp(redirect=True)<br />
frame = TestFrame()<br />
frame.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
<br />
<br />
15.11 <br />
1XML<br />
wx.TreeCtrlwx.TreeCtrl<br />
<br />
2<br />
AddRoot(text, image=-1, selImage=-1, data=None)<br />
rootwx.TreeItemIdwx.TreeItemId<br />
IDroot<br />
AppendItem(parent, text, image=-1, selImage=-1, data=None)<br />
parentIDwx.TreeItemId<br />
Delete(item)<br />
DeleteChildren(item)<br />
3<br />
<br />
root<br />
root<br />
501 / 565
4<br />
<br />
SetItemPyData(item, obj)Python<br />
wx.TreeCtrl<br />
OnCompareItems(item1, item2)item1item2ID<br />
5<br />
SetImageList(imageList)AssignImageList(imageList)<br />
<br />
<br />
6<br />
GetFirstChild(item)<br />
7SelectItem(item, select=True)<br />
ToggleItemSelection(item)<br />
IsSelected(item)Expand(item)<br />
Collapse(item)Toggle(item)<br />
8wx.TR_EDIT_LABELS<br />
esc<br />
wx.EVT_TREE_END_LABEL_EDIT <br />
wx.TreeEvent<br />
<br />
502 / 565
16 HTML<br />
* <strong>wxPython</strong>HTML<br />
* HTML<br />
* HTML(parser)<br />
* <br />
* HTML<br />
HTML<br />
HTMLHTML<br />
HTML<br />
<br />
<strong>wxPython</strong>HTML<br />
HTML<br />
<br />
<strong>wxPython</strong>HTML<br />
16.1 HTML<br />
<strong>wxPython</strong>HTML<br />
HTML<br />
URL<br />
16.1.1 <strong>wxPython</strong>HTML<br />
<br />
<strong>wxPython</strong>HTML<strong>wxPython</strong><br />
wx.html.HtmlW<strong>in</strong>dow16.1<br />
503 / 565
16.1<br />
16.116.1<br />
16.1 HtmlW<strong>in</strong>dow<br />
import wx<br />
import wx.html<br />
class MyHtmlFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self, parent, title):<br />
wx.Frame.__<strong>in</strong>it__(self, parent, -1, title)<br />
html = wx.html.HtmlW<strong>in</strong>dow(self)<br />
if ”gtk2” <strong>in</strong> wx.PlatformInfo:<br />
html.SetStandardFonts()<br />
html.SetPage(<br />
”Here is some formatted text ”<br />
”loaded from a str<strong>in</strong>g.”)<br />
app = wx.PySimpleApp()<br />
frm = MyHtmlFrame(None, ”Simple HTML”)<br />
frm.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
wx.html.HtmlW<strong>in</strong>dowwx.ScrolledW<strong>in</strong>dow<br />
<br />
wx.html.HtmlW<strong>in</strong>dow(parent, id=-1, pos=wx.DefaultPosition,<br />
size=wx.DefaultSize, style=wx.html.HW_SCROLLBAR_AUTO,<br />
504 / 565
name=”htmlW<strong>in</strong>dow”)<br />
<br />
wx.html.HW_SCROLLBAR_AUTOHTML<br />
wx.html.HW_SCROLLBAR_NEVER<br />
HTML<br />
wx.html.HW_NO_SelectION<br />
HTMLHTMLHTML<br />
wx.html.HtmlW<strong>in</strong>dow<br />
<br />
(css)JavaScript16.1HTML<br />
web<br />
16.1<br />
<br />
16.1 HTML<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
HTMLwx.Image<br />
wx.Image<br />
505 / 565
URLHTML<br />
16.1.2 URLHTML<br />
HTMLHTML<br />
HTML<br />
* SetPage(source)<br />
* AppendToPage(source)<br />
* LoadFile(filename)<br />
* LoadPage(location)<br />
SetPage(source)source<br />
HTML<br />
AppendToPage(source)HTML<br />
SetPage()AppendToPage()sourceHTML<br />
HTML<br />
<br />
<br />
LoadFile(filename)<br />
MIMEHTML<br />
<br />
<br />
<br />
<br />
LoadPage(location)URLlocationURL<br />
MIMEURL<br />
<br />
506 / 565
16.2HTML<br />
16.2<br />
16.216.2<br />
16.2 webHTML<br />
import wx<br />
import wx.html<br />
class MyHtmlFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self, parent, title):<br />
wx.Frame.__<strong>in</strong>it__(self, parent, -1, title, size=(600,400))<br />
html = wx.html.HtmlW<strong>in</strong>dow(self)<br />
if ”gtk2” <strong>in</strong> wx.PlatformInfo:<br />
html.SetStandardFonts()<br />
wx.CallAfter(<br />
html.LoadPage, ”http://www.wxpython.org”)<br />
app = wx.PySimpleApp()<br />
frm = MyHtmlFrame(None, ”Simple HTML Browser”)<br />
frm.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
507 / 565
16.2LoadPage()<br />
URLURL<br />
<br />
HTML<br />
16.2 HTML<br />
HTML<br />
<br />
<br />
16.2.1 <br />
wx.html.HtmlW<strong>in</strong>dow<br />
<br />
wx.html.HtmlW<strong>in</strong>dow<br />
16.2wx.html.HtmlW<strong>in</strong>dow<br />
<br />
<br />
HTML<br />
<br />
16.2 wx.html.HtmlW<strong>in</strong>dow<br />
OnCellClicked(cell, x, y, event)HTMLcell<br />
wx.html.HtmlCell<br />
wx.html.HtmlCellHTMLx,y<br />
eventcell<br />
OnL<strong>in</strong>kClicked()<br />
<br />
OnCellMouseHover(cell, x, y)HTML<br />
OnCellClicked()<br />
OnL<strong>in</strong>kClicked(l<strong>in</strong>k)<br />
URLLoadPageHtmlW<strong>in</strong>dow<br />
<br />
Pythonwebbrowser<br />
508 / 565
OnOpen<strong>in</strong>gURL(type, url)URL<br />
type<br />
wx.html.HTML_URL_PAGE, wx.html.HTML_URL_IMAGE, <br />
wx.html.HTML_URL_OTHER——wx.html.HTML_OPEN<br />
;wx.html.HTML_BLOCK;URL<br />
<br />
<br />
wx.html.HTML_OPEN<br />
OnSetTitle(title)HTML<br />
<br />
HTML<br />
16.2.2 HTML<br />
HTML<br />
Web<br />
<br />
HTMLHTML<br />
GetOpenedPage()URL<br />
LoadPage()<br />
URL<br />
GetOpenedAnchor()<br />
anchorLoadPage()<br />
HTMLGetOpenedPageTitle()<br />
<br />
<br />
SelectAll()<br />
SelectL<strong>in</strong>e(pos)SelectWord(pos)<br />
poswx.Po<strong>in</strong>t<br />
SelectionToText()<br />
ToText()<br />
wx.html.HtmlW<strong>in</strong>dow16.3<br />
<br />
509 / 565
16.3<br />
HistoryBack()False<br />
HistoryCanBack()TrueFalse<br />
HistoryCanForward()TrueFalse<br />
HistoryClear()<br />
HistoryForward()False<br />
<br />
SetFonts(normal_face, fixed_face, sizes=None)normal_face<br />
normal_face<br />
fixed_face<br />
fixed_facesizes7<br />
HTML2~<br />
+4None<br />
wx.html.HTML_FONT_SIZE_nn1~7<br />
HTML<br />
SetStandardFonts()<br />
GTK2<strong>wxPython</strong><br />
<br />
HTMLSetBorders(b)b<br />
<br />
<br />
HTML<br />
16.2.3 <br />
web<br />
<br />
<strong>wxPython</strong><br />
16.3web<br />
Html<br />
510 / 565
16.316.3<br />
16.3 HTML<br />
16.3 webHTMLW<strong>in</strong>dow<br />
#-*- encod<strong>in</strong>g:UTF-8 -*-<br />
import wx<br />
import wx.html<br />
class MyHtmlFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self, parent, title):<br />
wx.Frame.__<strong>in</strong>it__(self, parent, -1, title, size=(600,400))<br />
self.CreateStatusBar()<br />
html = wx.html.HtmlW<strong>in</strong>dow(self)<br />
if ”gtk2” <strong>in</strong> wx.PlatformInfo:<br />
html.SetStandardFonts()<br />
html.SetRelatedFrame(self, self.GetTitle() + ” -- %s”) #HTML<br />
html.SetRelatedStatusBar(0) #HTML<br />
wx.CallAfter(<br />
html.LoadPage, ”http://www.wxpython.org”)<br />
511 / 565
app = wx.PySimpleApp()<br />
frm = MyHtmlFrame(None, ”Simple HTML Browser”)<br />
frm.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
SetRelatedFrame(frame, format)<br />
frameformat<br />
“My <strong>wxPython</strong> Browser: %s”:%s<br />
%sHTML<br />
<br />
SetRelatedStatusBar(bar)<br />
SetRelatedFrame()bar<br />
0bar<br />
bar1,<br />
URL<br />
16.2.4 HTML<br />
HTMLHTML<br />
wx.html.HtmlEasyPr<strong>in</strong>t<strong>in</strong>g<br />
wx.html.HtmlEasyPr<strong>in</strong>t<strong>in</strong>g<br />
wx.html.HtmlEasyPr<strong>in</strong>t<strong>in</strong>g(name=”Pr<strong>in</strong>t<strong>in</strong>g”, parentW<strong>in</strong>dow=None)<br />
nameparentW<strong>in</strong>dow<br />
parentW<strong>in</strong>dow<br />
parentW<strong>in</strong>dowNone<br />
wx.html.HtmlEasyPr<strong>in</strong>t<strong>in</strong>g<strong>wxPython</strong><br />
<br />
<br />
<br />
Pr<strong>in</strong>terSetup()PageSetup()<br />
<br />
<br />
GetPr<strong>in</strong>tData()GetPageSetupData()GetPr<strong>in</strong>tData()<br />
512 / 565
wx.Pr<strong>in</strong>tDataGetPageSetupData()wx.PageSetupDialogData<br />
17<br />
<br />
SetFonts(normal_face, fixed_face, sizes)<br />
HTMLSetFonts()<br />
HTMLSetHeader(header, pg)<br />
SetFooter(footer, pg)headerfooter<br />
@PAGENUM@<br />
@PAGENUM@pg<br />
wx.PAGE_ALLwx.PAGE_EVENwx.PAGE_ODD<br />
pg<br />
<br />
<br />
<br />
PreviewFile(htmlfile)htmlfileHTML<br />
PreviewText(htmlText, basepath=””)htmlText<br />
HTMLbasepathURL<br />
TrueFalse<br />
wx.Pr<strong>in</strong>ter.GetLastError()<br />
17<br />
<br />
HTML<br />
Pr<strong>in</strong>tFile(htmlfile)Pr<strong>in</strong>tText(htmlText, basepath)<br />
<br />
True<br />
HTML<br />
16.3 HTML<br />
HTMLHTML<br />
HTML<strong>wxPython</strong><br />
HTML<br />
513 / 565
16.3.1 HTML(parser)<br />
<strong>wxPython</strong>HTML<br />
<br />
wx.html.HtmlW<strong>in</strong>dowPython<br />
HTMLPython<br />
htmllibHTMLParserPython<br />
“Beautiful Soup”<br />
wx.html.HtmlParser<br />
wx.html.HtmlW<strong>in</strong>Parserwx.html.HtmlParser<br />
wx.html.HtmlW<strong>in</strong>dowHTML<br />
wx.html.HtmlW<strong>in</strong>Parser<br />
HTML<br />
wx.html.HtmlW<strong>in</strong>Parser()wx.html.HtmlW<strong>in</strong>Parser<br />
wx.html.HtmlParser<br />
wx.html.HtmlW<strong>in</strong>Parser(wnd)wx.html.HtmlW<strong>in</strong>Parser()<br />
wx.html.HtmlW<strong>in</strong>dowwndHTML<br />
Parse(source)source<br />
HTML<br />
wx.html.HtmlW<strong>in</strong>Parserwx.html.HtmlCell<br />
HTMLHTML<br />
wx.html.HtmlCell<br />
wx.html.HtmlConta<strong>in</strong>erCell<br />
<br />
wx.html.HtmlConta<strong>in</strong>erCell<br />
Draw(dc, x, y, view_y1, view_y2)HTML<br />
<br />
wx.html.HtmlWidgetCell<br />
<strong>wxPython</strong>HTML<br />
HTML<br />
wx.html.HtmlWidgetCell<br />
wx.html.HtmlWidgetCell(wnd, w=0)<br />
514 / 565
wnd<strong>wxPython</strong>ww<br />
01100wnd<br />
w%<br />
HTML<br />
wxWidget<br />
<br />
16.3.2 <br />
HTML<br />
HTML<br />
HTML<br />
HTML<br />
16.4HTML<br />
16.4<br />
16.416.4<br />
16.4 <br />
import wx<br />
import wx.html<br />
515 / 565
page = ”””<br />
This silly example shows how custom tags can be def<strong>in</strong>ed and used <strong>in</strong> a<br />
wx.HtmlW<strong>in</strong>dow. We’ve def<strong>in</strong>ed a new tag, that will change<br />
the foreground color of the portions of the document that<br />
it encloses to some shade of blue. The tag handler can also use<br />
parameters specifed <strong>in</strong> the tag, for example:<br />
<br />
Sky Blue<br />
Midnight Blue<br />
Dark Blue<br />
Navy Blue<br />
<br />
<br />
“””<br />
class BlueTagHandler(wx.html.HtmlW<strong>in</strong>TagHandler):#<br />
def __<strong>in</strong>it__(self):<br />
wx.html.HtmlW<strong>in</strong>TagHandler.__<strong>in</strong>it__(self)<br />
def GetSupportedTags(self):#<br />
return ”BLUE”<br />
def HandleTag(self, tag):#<br />
old = self.GetParser().GetActualColor()<br />
clr = ”#0000FF”<br />
if tag.HasParam(“SHADE”):<br />
shade = tag.GetParam(“SHADE”)<br />
if shade.upper() == ”SKY”:<br />
clr = ”#3299CC”<br />
if shade.upper() == ”MIDNIGHT”:<br />
clr = ”#2F2F4F”<br />
elif shade.upper() == ”DARK”:<br />
clr = ”#00008B”<br />
elif shade.upper == ”NAVY”:<br />
clr = ”#23238E”<br />
516 / 565
self.GetParser().SetActualColor(clr)<br />
self.GetParser().GetConta<strong>in</strong>er().InsertCell(wx.html.HtmlColourCell(clr))<br />
self.ParseInner(tag)<br />
self.GetParser().SetActualColor(old)<br />
self.GetParser().GetConta<strong>in</strong>er().InsertCell(wx.html.HtmlColourCell(old))<br />
return True<br />
wx.html.HtmlW<strong>in</strong>Parser_AddTagHandler(BlueTagHandler)<br />
class MyHtmlFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self, parent, title):<br />
wx.Frame.__<strong>in</strong>it__(self, parent, -1, title)<br />
html = wx.html.HtmlW<strong>in</strong>dow(self)<br />
if ”gtk2” <strong>in</strong> wx.PlatformInfo:<br />
html.SetStandardFonts()<br />
html.SetPage(page)<br />
app = wx.PySimpleApp()<br />
frm = MyHtmlFrame(None, ”Custom HTML Tag Handler”)<br />
frm.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
wx.Html.TagHTML<br />
16.4wx.Html.Tag<br />
<br />
16.4 wx.Html.Tag<br />
GetAllParams()<br />
<br />
GetName()<br />
HasParam(param)True<br />
517 / 565
GetParam(param, with_commas=False)param<br />
with_commas True<br />
GetParamAsColour(param)<br />
wx.ColorGetParamAsInt(param)<br />
HasEnd<strong>in</strong>g()Truefalse<br />
HTMLwx.html.HtmlW<strong>in</strong>TagHandler<br />
<br />
GetSupportedTags()<br />
<br />
GetSupportedTags(self):<br />
return ”MYTAG,MYTAGPARAM”<br />
HandleTag(tag)HandleTag(tag)<br />
<br />
GetParser()<br />
HandleTag(tag)<br />
1<br />
2<br />
3<br />
4<br />
GetParser()<br />
<br />
Conta<strong>in</strong>er()<br />
wx.html.HTMLCellInsertCell(cell)<br />
<br />
<br />
<br />
OpenConta<strong>in</strong>er()<br />
InsertCell(cell)<br />
CloseConta<strong>in</strong>er()<br />
OpenConta<strong>in</strong>er()CloseConta<strong>in</strong>er()<br />
HTML<br />
518 / 565
——<br />
<br />
<br />
parser = self.GetParser()<br />
parser.CloseConta<strong>in</strong>er()#<br />
parser.OpenConta<strong>in</strong>er()#<br />
# <br />
parser.CloseConta<strong>in</strong>er()<br />
parser.OpenConta<strong>in</strong>er()<br />
<br />
16.3.3 <br />
HTMLMIMEtext/html, text/txt, <br />
image/*<strong>wxPython</strong><br />
HTMLHTML<br />
<br />
wx.html.HtmlFilter<br />
XMLPython<br />
filterwx.html.HtmlFilter<br />
wx.html.HtmlFilter<br />
CanRead(file)filewx.FSFile<strong>wxPython</strong><br />
wx.FSFile<br />
GetMimeType()MIMEMIME<br />
GetLocation()<br />
URLCanRead()<br />
TrueFalsePythonCanRead()<br />
CanRead(self, file):<br />
return file.GetLocation().endswith(‘.py’)<br />
ReadFile(file)file<br />
HTML<br />
519 / 565
wxWidgets C++<br />
file.GetLocation()Python<br />
wx.html.HtmlW<strong>in</strong>dow<br />
wx.html.HtmlW<strong>in</strong>dowAddFilter(filter)filter<br />
wx.html.HtmlFilter<br />
CanRead()<br />
16.3.4 HTML<br />
wx.html.HtmlW<strong>in</strong>dow<br />
HTMLW<strong>in</strong>dows<br />
wx.lib.iew<strong>in</strong>.IEHtmlW<strong>in</strong>dowInternet Explorer ActiveX<br />
ie<br />
IE<strong>wxPython</strong>HTML<br />
<br />
wx.lib.iew<strong>in</strong>.IEHtmlW<strong>in</strong>dow(self, parent, ID=-1,<br />
pos=wx.DefaultPosition, size=wx.DefaultSize, style=0,<br />
name=’IEHtmlW<strong>in</strong>dow’)<br />
parentID<strong>wxPython</strong> IDIE<br />
HTMLIELoadStr<strong>in</strong>g(html)<br />
htmlHTMLLoadStream(stream)<br />
PythonLoadStr<strong>in</strong>g(URL)<br />
URLGetText(asHTML)<br />
asHTMLTrueHTML<br />
<br />
wxMozilla(http://<br />
wxmozilla.sourceforge.net)Mozilla Gecko<br />
<strong>wxPython</strong>wxMozillaW<strong>in</strong>dowsL<strong>in</strong>ux<br />
Mac OS X<br />
520 / 565
16.4 <br />
1HTMLInternet<strong>wxPython</strong>HTML<br />
HTMLHTML<br />
wx.html.HtmlW<strong>in</strong>dowHTMLHTML<br />
<br />
2HTMLURL<br />
<br />
HTML<br />
HTML<br />
wx.Html.HtmlEasyPr<strong>in</strong>t<strong>in</strong>g<br />
3<strong>wxPython</strong>HTML<br />
HTML<br />
<br />
4HTML<br />
IE<strong>wxPython</strong>W<strong>in</strong>dows<br />
Mozilla Gecko HTML<strong>wxPython</strong><br />
17 <strong>wxPython</strong><br />
521 / 565
17 <strong>wxPython</strong><br />
<br />
* <strong>wxPython</strong><br />
* <br />
* <br />
* <br />
* <br />
16<strong>wxPython</strong><br />
wx.HtmlEasyPr<strong>in</strong>t<strong>in</strong>gHTMLHTML<br />
<br />
<strong>wxPython</strong><br />
<br />
<br />
wx.Pr<strong>in</strong>tout<br />
wx.Pr<strong>in</strong>ter<br />
wx.Pr<strong>in</strong>tPreview<br />
<br />
17.1 <strong>wxPython</strong><br />
wx.Pr<strong>in</strong>toutwx.Pr<strong>in</strong>tout<br />
wx.Pr<strong>in</strong>toutwx.Pr<strong>in</strong>tout<br />
7<br />
<strong>wxPython</strong>17.1<br />
<br />
522 / 565
17.1<br />
17.1.1 <br />
wx.Pr<strong>in</strong>ter<br />
<br />
wx.Pr<strong>in</strong>ter(data=None)<br />
datawx.Pr<strong>in</strong>tDialogData<br />
wx.Pr<strong>in</strong>terPr<strong>in</strong>t(parent, pr<strong>in</strong>tout, prompt=True)parent<br />
pr<strong>in</strong>toutwx.Pr<strong>in</strong>tout<br />
promptTrue<strong>wxPython</strong><br />
Pr<strong>in</strong>t()wx.Pr<strong>in</strong>tout<br />
OnPreparePr<strong>in</strong>t()OnPreparePr<strong>in</strong>t()wx.Pr<strong>in</strong>tout<br />
<br />
OnBeg<strong>in</strong>Pr<strong>in</strong>t<strong>in</strong>g()<br />
——<br />
OnBeg<strong>in</strong>Pr<strong>in</strong>t<strong>in</strong>g()<br />
523 / 565
OnBeg<strong>in</strong>Document(startPage, endPage)startPage, endPage<br />
<strong>wxPython</strong><br />
<br />
wx.DC.StartDoc()<strong>wxPython</strong><br />
base_OnBeg<strong>in</strong>Document(startPage, endPage)<br />
OnBeg<strong>in</strong>DocumentFalse<br />
OnPr<strong>in</strong>tPage(pageNum)<br />
pageNum<br />
GetDC()GetDC()<br />
W<strong>in</strong>dows<br />
GetDC()wx.Pr<strong>in</strong>terDC<br />
wx.PostScriptDC<br />
GetDC()wx.MemoryDC<br />
<br />
OnEndDocument()<br />
OnEndDocument()<br />
base_OnEndDocument()base_OnEndDocument()wx.DC.EndDoc()<br />
OnEndPr<strong>in</strong>t<strong>in</strong>g()<br />
<br />
wx.Pr<strong>in</strong>toutHasPage(pageNum)<br />
pageNum<br />
TrueFalse<br />
17.1.2 <br />
<br />
<br />
17.2<br />
524 / 565
17.1<br />
17.1<br />
<br />
17.1 <br />
import wx<br />
import os<br />
FONTSIZE = 10<br />
class TextDocPr<strong>in</strong>tout(wx.Pr<strong>in</strong>tout):<br />
”””<br />
A pr<strong>in</strong>tout class that is able to pr<strong>in</strong>t simple text documents.<br />
Does not handle page numbers or titles, and it assumes that no<br />
l<strong>in</strong>es are longer than what will fit with<strong>in</strong> the page width. Those<br />
features are left as an exercise for the reader. ;-)<br />
”””<br />
def __<strong>in</strong>it__(self, text, title, marg<strong>in</strong>s):<br />
525 / 565
wx.Pr<strong>in</strong>tout.__<strong>in</strong>it__(self, title)<br />
self.l<strong>in</strong>es = text.split(‘\n’)<br />
self.marg<strong>in</strong>s = marg<strong>in</strong>s<br />
def HasPage(self, page):<br />
return page
self.x1 = topLeft.x * self.logUnitsMM<br />
self.y1 = topLeft.y * self.logUnitsMM<br />
self.x2 = dc.DeviceToLogicalXRel(dw) - bottomRight.x * self.logUnitsMM<br />
self.y2 = dc.DeviceToLogicalYRel(dh) - bottomRight.y * self.logUnitsMM<br />
# use a 1mm buffer around the <strong>in</strong>side of the box, and a few<br />
# pixels between each l<strong>in</strong>e<br />
self.pageHeight = self.y2 - self.y1 - 2*self.logUnitsMM<br />
font = wx.Font(FONTSIZE, wx.TELETYPE, wx.NORMAL, wx.NORMAL)<br />
dc.SetFont(font)<br />
self.l<strong>in</strong>eHeight = dc.GetCharHeight()<br />
self.l<strong>in</strong>esPerPage = <strong>in</strong>t(self.pageHeight/self.l<strong>in</strong>eHeight)<br />
def OnPreparePr<strong>in</strong>t<strong>in</strong>g(self):<br />
# calculate the number of pages<br />
dc = self.GetDC()<br />
self.CalculateScale(dc)<br />
self.CalculateLayout(dc)<br />
self.numPages = len(self.l<strong>in</strong>es) / self.l<strong>in</strong>esPerPage<br />
if len(self.l<strong>in</strong>es) % self.l<strong>in</strong>esPerPage != 0:<br />
self.numPages += 1<br />
def OnPr<strong>in</strong>tPage(self, page):<br />
dc = self.GetDC()<br />
self.CalculateScale(dc)<br />
self.CalculateLayout(dc)<br />
# draw a page outl<strong>in</strong>e at the marg<strong>in</strong> po<strong>in</strong>ts<br />
dc.SetPen(wx.Pen(“black”, 0))<br />
dc.SetBrush(wx.TRANSPARENT_BRUSH)<br />
r = wx.RectPP((self.x1, self.y1),<br />
(self.x2, self.y2))<br />
dc.DrawRectangleRect(r)<br />
dc.SetClipp<strong>in</strong>gRect(r)<br />
# Draw the text l<strong>in</strong>es for this page<br />
l<strong>in</strong>e = (page-1) * self.l<strong>in</strong>esPerPage<br />
x = self.x1 + self.logUnitsMM<br />
527 / 565
y = self.y1 + self.logUnitsMM<br />
while l<strong>in</strong>e < (page * self.l<strong>in</strong>esPerPage):<br />
dc.DrawText(self.l<strong>in</strong>es[l<strong>in</strong>e], x, y)<br />
y += self.l<strong>in</strong>eHeight<br />
l<strong>in</strong>e += 1<br />
if l<strong>in</strong>e >= len(self.l<strong>in</strong>es):<br />
break<br />
return True<br />
class Pr<strong>in</strong>tFrameworkSample(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, size=(640, 480),<br />
title=”Pr<strong>in</strong>t Framework Sample”)<br />
self.CreateStatusBar()<br />
# A text widget to display the doc and let it be edited<br />
self.tc = wx.TextCtrl(self, -1, ””,<br />
style=wx.TE_MULTILINE|wx.TE_DONTWRAP)<br />
self.tc.SetFont(wx.Font(FONTSIZE, wx.TELETYPE, wx.NORMAL, wx.NOR<br />
MAL))<br />
filename = os.path.jo<strong>in</strong>(os.path.dirname(__file__), ”sample-text.txt”)<br />
self.tc.SetValue(open(filename).read())<br />
self.tc.B<strong>in</strong>d(wx.EVT_SET_FOCUS, self.OnClearSelection)<br />
wx.CallAfter(self.tc.SetInsertionPo<strong>in</strong>t, 0)<br />
# Create the menu and menubar<br />
menu = wx.Menu()<br />
item = menu.Append(-1, ”Page Setup...\tF5”,<br />
”Set up page marg<strong>in</strong>s and etc.”)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnPageSetup, item)<br />
item = menu.Append(-1, ”Pr<strong>in</strong>t Setup...\tF6”,<br />
”Set up the pr<strong>in</strong>ter options, etc.”)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnPr<strong>in</strong>tSetup, item)<br />
item = menu.Append(-1, ”Pr<strong>in</strong>t Preview...\tF7”,<br />
”View the pr<strong>in</strong>tout on-screen”)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnPr<strong>in</strong>tPreview, item)<br />
item = menu.Append(-1, ”Pr<strong>in</strong>t...\tF8”, ”Pr<strong>in</strong>t the document”)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnPr<strong>in</strong>t, item)<br />
menu.AppendSeparator()<br />
528 / 565
item = menu.Append(-1, ”E&xit”, ”Close this application”)<br />
self.B<strong>in</strong>d(wx.EVT_MENU, self.OnExit, item)<br />
menubar = wx.MenuBar()<br />
menubar.Append(menu, ”&File”)<br />
self.SetMenuBar(menubar)<br />
# <strong>in</strong>itialize the pr<strong>in</strong>t data and set some default values<br />
self.pdata = wx.Pr<strong>in</strong>tData()<br />
self.pdata.SetPaperId(wx.PAPER_LETTER)<br />
self.pdata.SetOrientation(wx.PORTRAIT)<br />
self.marg<strong>in</strong>s = (wx.Po<strong>in</strong>t(15,15), wx.Po<strong>in</strong>t(15,15))<br />
def OnExit(self, evt):<br />
self.Close()<br />
def OnClearSelection(self, evt):<br />
evt.Skip()<br />
wx.CallAfter(self.tc.SetInsertionPo<strong>in</strong>t,<br />
self.tc.GetInsertionPo<strong>in</strong>t())<br />
def OnPageSetup(self, evt):<br />
data = wx.PageSetupDialogData()<br />
data.SetPr<strong>in</strong>tData(self.pdata)<br />
data.SetDefaultM<strong>in</strong>Marg<strong>in</strong>s(True)<br />
data.SetMarg<strong>in</strong>TopLeft(self.marg<strong>in</strong>s[0])<br />
data.SetMarg<strong>in</strong>BottomRight(self.marg<strong>in</strong>s[1])<br />
dlg = wx.PageSetupDialog(self, data)<br />
if dlg.ShowModal() == wx.ID_OK:<br />
data = dlg.GetPageSetupData()<br />
self.pdata = wx.Pr<strong>in</strong>tData(data.GetPr<strong>in</strong>tData()) # force a copy<br />
self.pdata.SetPaperId(data.GetPaperId())<br />
self.marg<strong>in</strong>s = (data.GetMarg<strong>in</strong>TopLeft(),<br />
data.GetMarg<strong>in</strong>BottomRight())<br />
dlg.Destroy()<br />
529 / 565
def OnPr<strong>in</strong>tSetup(self, evt):<br />
data = wx.Pr<strong>in</strong>tDialogData(self.pdata)<br />
dlg = wx.Pr<strong>in</strong>tDialog(self, data)<br />
dlg.GetPr<strong>in</strong>tDialogData().SetSetupDialog(True)<br />
dlg.ShowModal();<br />
data = dlg.GetPr<strong>in</strong>tDialogData()<br />
self.pdata = wx.Pr<strong>in</strong>tData(data.GetPr<strong>in</strong>tData()) # force a copy<br />
dlg.Destroy()<br />
def OnPr<strong>in</strong>tPreview(self, evt):<br />
data = wx.Pr<strong>in</strong>tDialogData(self.pdata)<br />
text = self.tc.GetValue()<br />
pr<strong>in</strong>tout1 = TextDocPr<strong>in</strong>tout(text, ”title”, self.marg<strong>in</strong>s)<br />
pr<strong>in</strong>tout2 = None #TextDocPr<strong>in</strong>tout(text, ”title”, self.marg<strong>in</strong>s)<br />
preview = wx.Pr<strong>in</strong>tPreview(pr<strong>in</strong>tout1, pr<strong>in</strong>tout2, data)<br />
if not preview.Ok():<br />
wx.MessageBox(“Unable to create Pr<strong>in</strong>tPreview!”, ”Error”)<br />
else:<br />
# create the preview frame such that it overlays the app frame<br />
frame = wx.PreviewFrame(preview, self, ”Pr<strong>in</strong>t Preview”,<br />
pos=self.GetPosition(),<br />
size=self.GetSize())<br />
frame.Initialize()<br />
frame.Show()<br />
def OnPr<strong>in</strong>t(self, evt):<br />
data = wx.Pr<strong>in</strong>tDialogData(self.pdata)<br />
pr<strong>in</strong>ter = wx.Pr<strong>in</strong>ter(data)<br />
text = self.tc.GetValue()<br />
pr<strong>in</strong>tout = TextDocPr<strong>in</strong>tout(text, ”title”, self.marg<strong>in</strong>s)<br />
useSetupDialog = True<br />
if not pr<strong>in</strong>ter.Pr<strong>in</strong>t(self, pr<strong>in</strong>tout, useSetupDialog) \<br />
and pr<strong>in</strong>ter.GetLastError() == wx.PRINTER_ERROR:<br />
wx.MessageBox(<br />
”There was a problem pr<strong>in</strong>t<strong>in</strong>g.\n”<br />
”Perhaps your current pr<strong>in</strong>ter is not set correctly”,<br />
530 / 565
”Pr<strong>in</strong>t<strong>in</strong>g Error”, wx.OK)<br />
else:<br />
data = pr<strong>in</strong>ter.GetPr<strong>in</strong>tDialogData()<br />
self.pdata = wx.Pr<strong>in</strong>tData(data.GetPr<strong>in</strong>tData()) # force a copy<br />
pr<strong>in</strong>tout.Destroy()<br />
app = wx.PySimpleApp()<br />
frm = Pr<strong>in</strong>tFrameworkSample()<br />
frm.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
17.2<br />
<br />
<br />
OnPreparePr<strong>in</strong>t<strong>in</strong>g()OnPr<strong>in</strong>tPage()<br />
OnPr<strong>in</strong>t()<br />
wx.Pr<strong>in</strong>tout<br />
17.1.3 wx.Pr<strong>in</strong>tout<br />
wx.Pr<strong>in</strong>toutget*<br />
17.1<br />
17.1 wx.Pr<strong>in</strong>tout<br />
GetDC()<br />
GetPageInfo()<br />
(m<strong>in</strong>Page, maxPage, pageFrom, pageTo)m<strong>in</strong>Page, maxPage<br />
132000pageFrom, pageTo<br />
1<br />
GetPageSizeMM()(w, h)<br />
<br />
531 / 565
GetPageSizePixels()(w, h)<br />
<br />
<br />
GetPPIPr<strong>in</strong>ter()(w, h)<br />
<br />
GetPPIScreen()(w, h)<br />
<br />
GetTitle()<br />
<br />
17.2 <br />
<br />
<strong>wxPython</strong><br />
<br />
<br />
17.2.1 <br />
17.3<br />
17.3<br />
532 / 565
wx.Pr<strong>in</strong>tDialog<br />
<br />
wx.Pr<strong>in</strong>tDialog(parent, data=None)<br />
parentdata<br />
wx.Pr<strong>in</strong>tDialogData<br />
<br />
ShowModal()<br />
ShowModal()wx.ID_OK<br />
wx.ID_CANCEL GetPr<strong>in</strong>tDialogData()<br />
GetPr<strong>in</strong>tDC()<br />
GetPr<strong>in</strong>tDC()<br />
None17.1OnPr<strong>in</strong>tSetup()<br />
<br />
wx.Pr<strong>in</strong>tData<br />
wx.Pr<strong>in</strong>tData<br />
wx.Pr<strong>in</strong>tDialogData()wx.Pr<strong>in</strong>tDialogData<br />
<br />
wx.Pr<strong>in</strong>tDialogData<br />
EnableHelp(enable)<br />
EnablePageNumbers(enable)<br />
EnablePr<strong>in</strong>tToFile(enable)EnableSelection(enable)<br />
<br />
17.2<br />
<br />
17.2 wx.Pr<strong>in</strong>tDialogData<br />
GetAllPages()True<br />
SetCollate(flag)<br />
GetCollate()True<br />
533 / 565
SetFromPage(page)<br />
GetFromPage()<br />
<br />
SetMaxPage(page)<br />
GetMaxPage()<br />
SetM<strong>in</strong>Page(page)<br />
GetM<strong>in</strong>Page()<br />
SetNoCopies()<br />
GetNoCopies()<br />
SetPr<strong>in</strong>tData(pr<strong>in</strong>tData)<br />
GetPr<strong>in</strong>tData()wx.Pr<strong>in</strong>tData<br />
SetPr<strong>in</strong>tToFile(flag)<br />
GetPr<strong>in</strong>tToFile()True“<br />
”<strong>wxPython</strong><br />
SetSelection(flag)<br />
GetSelection()True<br />
SetToPage(page)<br />
GetToPage()<br />
GetPr<strong>in</strong>tData()wx.Pr<strong>in</strong>tData<br />
17.3<br />
wx.Pr<strong>in</strong>tData<br />
17.3 wx.Pr<strong>in</strong>tData<br />
SetColour(flag)<br />
GetColour()True<br />
SetDuplex(mode)<br />
GetDuplex()wx.DUPLEX_SIMPLE<br />
wx.DUPLEX_HORIZONTAL<br />
wx.DUPLEX_VERTICAL<br />
SetOrientation(orientation)<br />
GetOrientation()wx.LANDSCAPE<br />
wx.PORTRAIT<br />
534 / 565
SetPaperId(paperId)<br />
GetPaperId()<br />
wx.PAPER_LETTER, wx.PAPER_LEGAL, wx.PAPER_A4<br />
IDwxWidgets<br />
SetPr<strong>in</strong>terName(pr<strong>in</strong>terName)<br />
GetPr<strong>in</strong>terName()<br />
<br />
SetQuality(quality)<br />
GetQuality()set*<br />
wx.PRINT_QUALITY_DRAFT, wx.PRINT_QUALITY_HIGH, wx.PRINT_QUALITY_<br />
MEDIUM, wx.PRINT_QUALITY_LOWget*<br />
<br />
17.3 <br />
17.4<br />
<br />
17.4<br />
17.3.1 <br />
wx.PageSetupDialog<br />
<br />
535 / 565
wx.PageSetupDialog(parent, data=None)<br />
parentdatawx.PageSetupDialogData<br />
None<br />
ShowModal()<br />
wx.ID_OKwx.ID_CANCEL<br />
GetPageSetupDialogData()<br />
GetPageSetupDialogData()wx.PageSetupDialogData<br />
<br />
17.3.2 <br />
wx.PageSetupDialogData17.4<br />
<br />
True<br />
17.4 wx.PageSetupDialogData<br />
GetDefaultM<strong>in</strong>Marg<strong>in</strong>s()<br />
SetDefaultM<strong>in</strong>Marg<strong>in</strong>s(flag)TrueW<strong>in</strong>dows<br />
<br />
<br />
GetDefaultInfo()<br />
SetDefaultInfo(flag)TrueW<strong>in</strong>dows<br />
<br />
<br />
EnableHelp(flag)<br />
GetEnableHelp()True<br />
EnableMarg<strong>in</strong>s(flag)<br />
GetEnableMarg<strong>in</strong>s()True<br />
EnableOrientation(flag)<br />
GetEnableOrientation()True<br />
<br />
EnablePaper(flag)<br />
GetEnablePaper()True<br />
<br />
536 / 565
EnablePr<strong>in</strong>ter(flag)<br />
GetEnablePr<strong>in</strong>ter()True<br />
17.5wx.PageSetupDialogData<br />
<br />
17.5 wx.PageSetupDialogData<br />
GetMarg<strong>in</strong>TopLeft()<br />
SetMarg<strong>in</strong>TopLeft(pt)get*wx.Po<strong>in</strong>txy<br />
set*wx.Po<strong>in</strong>tPython<br />
GetMarg<strong>in</strong>BottomRight()<br />
SetMarg<strong>in</strong>BottomRight(pt)get*wx.Po<strong>in</strong>tx<br />
yset*wx.Po<strong>in</strong>tPython<br />
<br />
GetM<strong>in</strong>Marg<strong>in</strong>TopLeft()<br />
SetM<strong>in</strong>Marg<strong>in</strong>TopLeft(pt)GetMarg<strong>in</strong>TopLeft()<br />
<br />
GetM<strong>in</strong>Marg<strong>in</strong>BottomRight()<br />
SetM<strong>in</strong>Marg<strong>in</strong>BottomRight(pt)GetMarg<strong>in</strong>BottomRight()<br />
<br />
GetPaperId()<br />
SetPaperId(id)<strong>wxPython</strong>wx.Pr<strong>in</strong>terData<br />
<br />
GetPaperSize()<br />
SetPaperSize(size)get*wx.Size<br />
<br />
GetPr<strong>in</strong>tData()<br />
SetPr<strong>in</strong>tData(pr<strong>in</strong>tData)get*wx.Pr<strong>in</strong>tData<br />
<br />
<br />
537 / 565
17.4 <br />
<br />
wx.Pr<strong>in</strong>ter<br />
17.1<br />
OnPr<strong>in</strong>t()<br />
<br />
wx.Pr<strong>in</strong>tout<br />
wx.Pr<strong>in</strong>tDialogData<br />
<br />
wx.Pr<strong>in</strong>ter(data=None)data<br />
wx.Pr<strong>in</strong>tDialogData<br />
<br />
Pr<strong>in</strong>t()<br />
Pr<strong>in</strong>t(parent, pr<strong>in</strong>tout, prompt=True)<br />
parentpr<strong>in</strong>tout<br />
wx.Pr<strong>in</strong>toutpromptTrue<br />
<br />
Pr<strong>in</strong>t()TrueGetLastError()<br />
wx.PRINTER_CANCELLED<br />
wx.PRINTER_ERROR<br />
wx.PRINTER_NO_ERRORPr<strong>in</strong>t()True<br />
<br />
wx.Pr<strong>in</strong>ter<br />
* CreateAbortW<strong>in</strong>dow(parent,pr<strong>in</strong>tout)<br />
parentpr<strong>in</strong>toutPr<strong>in</strong>t()<br />
Abort()True<br />
* Pr<strong>in</strong>tDialog(parent)<br />
GetPr<strong>in</strong>tDialogData()<br />
538 / 565
17.5 <br />
<br />
<br />
<br />
<br />
wx.Pr<strong>in</strong>tPreview<br />
wx.Pr<strong>in</strong>tPreviewwx.Pr<strong>in</strong>ter<br />
wx.Pr<strong>in</strong>tPreview(pr<strong>in</strong>tout, pr<strong>in</strong>toutForPr<strong>in</strong>t<strong>in</strong>g, data=None)<br />
pr<strong>in</strong>toutwx.Pr<strong>in</strong>tout<br />
pr<strong>in</strong>toutForPr<strong>in</strong>t<strong>in</strong>gwx.Pr<strong>in</strong>toutNone<br />
Pr<strong>in</strong>tpr<strong>in</strong>toutForPr<strong>in</strong>t<strong>in</strong>g<br />
pr<strong>in</strong>toutForPr<strong>in</strong>t<strong>in</strong>gNonePr<strong>in</strong>t<br />
<br />
pr<strong>in</strong>toutpr<strong>in</strong>toutForPr<strong>in</strong>t<strong>in</strong>gdatawx.Pr<strong>in</strong>tData<br />
wx.Pr<strong>in</strong>tDialogDatadata<br />
17.1OnPr<strong>in</strong>tPreview()<br />
<br />
<br />
wx.Pr<strong>in</strong>tPreview<br />
wx.Pr<strong>in</strong>tPreviewwx.PreviewFramewx.PreviewFrame<br />
wx.Framewx.Frame<br />
wx.PreviewFrame<br />
wx.PreviewFrame(preview, parent, title, pos=wx.DefaultPosition,<br />
size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE,<br />
name=”frame”)<br />
previewwx.Pr<strong>in</strong>tPreview<br />
wx.Framewx.PreviewFrame<br />
<br />
539 / 565
wx.PreviewFrameInitialize()<br />
Show()<br />
CreateControlBar()<br />
CreateCanvas()wx.PreviewControlBarwx.PreviewCanvas<br />
(canvas)/<br />
<br />
17.6 <br />
1<strong>wxPython</strong>HTML<br />
<br />
wx.Pr<strong>in</strong>toutwx.Pr<strong>in</strong>terwx.Pr<strong>in</strong>tPreview<br />
2wx.Pr<strong>in</strong>tout<br />
OnPr<strong>in</strong>tPage()<br />
<br />
3<strong>wxPython</strong><br />
wx.Pr<strong>in</strong>tDialog<br />
wx.PageSetupDialog<br />
<br />
4wx.Pr<strong>in</strong>ter<br />
wx.Pr<strong>in</strong>tPreview<br />
<br />
18 <strong>wxPython</strong><br />
540 / 565
18 <strong>wxPython</strong><br />
<br />
* <br />
* <br />
* <br />
* wx.Timer<br />
* <strong>wxPython</strong><br />
18.1 <br />
<strong>wxPython</strong><br />
wx.DataObjectwx.DataObject<br />
<br />
<br />
<br />
* source()<br />
* clipboard()<br />
* target()<br />
source<br />
wx.DataObjectsource<br />
<br />
clipboard<br />
<br />
targetwx.DataObject<br />
<br />
18.1.1 <br />
<br />
wx.DataObjectwx.DataObject<br />
<br />
<br />
541 / 565
<strong>wxPython</strong>wx.DataObject<br />
<br />
wx.TextDataObject<br />
<br />
wx.TextDataObject(text=””)<br />
textText(text)<br />
GetText()GetTextLength()<br />
<br />
<br />
<strong>wxPython</strong>wx.TheClipboard<br />
Open()True<br />
False<br />
<br />
<br />
Close()<br />
<br />
18.1.2 <br />
<br />
SetData(data)data<br />
wx.DataObjectClear()<br />
Flush()<br />
<strong>wxPython</strong><br />
<br />
<br />
text_data = wx.TextDataObject(“hi there”)<br />
if wx.TheClipboard.Open():<br />
wx.TheClipboard.SetData(text_data)<br />
wx.TheClipboard.Close()<br />
<br />
542 / 565
18.1.3 <br />
<br />
GetData(data)datawx.DataObject<br />
<br />
True<br />
wx.TextDataObjectTrue<br />
<br />
text_data = wx.TextDataObject()<br />
if wx.TheClipboard.Open():<br />
success = wx.TheClipboard.GetData(text_data)<br />
wx.TheClipboard.Close()<br />
if success:<br />
return text_data.GetText()<br />
<br />
<strong>wxPython</strong><br />
<br />
18.1.4 <br />
<br />
<br />
18.1<br />
543 / 565
18.1<br />
18.118.1<br />
18.1 <br />
#-*- encod<strong>in</strong>g:UTF-8 -*-<br />
import wx<br />
t1_text = ”””\<br />
The whole contents of this control<br />
will be placed <strong>in</strong> the system’s<br />
clipboard when you click the copy<br />
button below.<br />
“””<br />
t2_text = ”””\<br />
If the clipboard conta<strong>in</strong>s a text<br />
data object then it will be placed<br />
<strong>in</strong> this control when you click<br />
the paste button below. Try<br />
copy<strong>in</strong>g to and past<strong>in</strong>g from<br />
other applications too!<br />
“””<br />
class MyFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, title=”Clipboard”,<br />
544 / 565
size=(500,300))<br />
p = wx.Panel(self)<br />
# create the controls<br />
self.t1 = wx.TextCtrl(p, -1, t1_text,<br />
style=wx.TE_MULTILINE|wx.HSCROLL)<br />
self.t2 = wx.TextCtrl(p, -1, t2_text,<br />
style=wx.TE_MULTILINE|wx.HSCROLL)<br />
copy = wx.Button(p, -1, ”Copy”)<br />
paste = wx.Button(p, -1, ”Paste”)<br />
# setup the layout with sizers<br />
fgs = wx.FlexGridSizer(2, 2, 5, 5)<br />
fgs.AddGrowableRow(0)<br />
fgs.AddGrowableCol(0)<br />
fgs.AddGrowableCol(1)<br />
fgs.Add(self.t1, 0, wx.EXPAND)<br />
fgs.Add(self.t2, 0, wx.EXPAND)<br />
fgs.Add(copy, 0, wx.EXPAND)<br />
fgs.Add(paste, 0, wx.EXPAND)<br />
border = wx.BoxSizer()<br />
border.Add(fgs, 1, wx.EXPAND|wx.ALL, 5)<br />
p.SetSizer(border)<br />
# B<strong>in</strong>d events<br />
self.B<strong>in</strong>d(wx.EVT_BUTTON, self.OnDoCopy, copy)<br />
self.B<strong>in</strong>d(wx.EVT_BUTTON, self.OnDoPaste, paste)<br />
def OnDoCopy(self, evt):#Copy<br />
data = wx.TextDataObject()<br />
data.SetText(self.t1.GetValue())<br />
if wx.TheClipboard.Open():<br />
wx.TheClipboard.SetData(data)#<br />
wx.TheClipboard.Close()<br />
else:<br />
wx.MessageBox(“Unable to open the clipboard”, ”Error”)<br />
def OnDoPaste(self, evt):#Paste<br />
success = False<br />
data = wx.TextDataObject()<br />
545 / 565
if wx.TheClipboard.Open():<br />
success = wx.TheClipboard.GetData(data)#<br />
wx.TheClipboard.Close()<br />
if success:<br />
self.t2.SetValue(data.GetText())#<br />
else:<br />
wx.MessageBox(<br />
”There is no data <strong>in</strong> the clipboard <strong>in</strong> the required format”,<br />
”Error”)<br />
app = wx.PySimpleApp()<br />
frm = MyFrame()<br />
frm.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
<br />
<br />
18.1.5 <br />
<br />
wx.BitmapDataObjectget*set*GetBitmap()<br />
SetBitmap(bitmap)wx.Bitmap<br />
<br />
wx.FileDataObject<br />
18.2<br />
<br />
GetFilenames()<br />
<br />
AddFile(file)<br />
<br />
<br />
<br />
18.2 <br />
546 / 565
<strong>wxPython</strong>wx.DataObject<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
1<br />
2wx.DropSource<br />
3<br />
4<br />
<br />
<br />
wx.DataObject<br />
<br />
<br />
wx.DropSource<br />
wx.DropSource<br />
wx.DropSource(w<strong>in</strong>, iconCopy=wx.NullIconOrCursor,<br />
iconMove=wx.NullIconOrCursor,<br />
iconNone=wx.NullIconOrCursor)<br />
w<strong>in</strong><br />
<br />
W<strong>in</strong>dows<br />
wx.CursorUnixwx.Icon——Mac OS<br />
<br />
547 / 565
wx.DropSourceSetData(data)<br />
wx.DropSource<br />
<br />
DoDragDrop(flags=wx.Drag_CopyOnly)<br />
flags<br />
wx.Drag_AllowMovewx.Drag_DefaultMove<br />
<br />
wx.Drag_CopyOnly<br />
<br />
DoDragDrop()<br />
DoDragDrop()<br />
<br />
wx.DragCancel<br />
wx.DragCopy <br />
wx.DragMove <br />
wx.DragNone <br />
<br />
<br />
18.2.1 <br />
18.2<br />
Microsoft word18.2<br />
<br />
548 / 565
18.2<br />
18.2 <br />
#-*- encod<strong>in</strong>g:UTF-8 -*-<br />
import wx<br />
class DragController(wx.Control):<br />
”””<br />
Just a little control to handle dragg<strong>in</strong>g the text from a text<br />
control. We use a separate control so as to not <strong>in</strong>terfere with<br />
the native drag-select functionality of the native text control.<br />
”””<br />
def __<strong>in</strong>it__(self, parent, source, size=(25,25)):<br />
wx.Control.__<strong>in</strong>it__(self, parent, -1, size=size,<br />
style=wx.SIMPLE_BORDER)<br />
self.source = source<br />
self.SetM<strong>in</strong>Size(size)<br />
self.B<strong>in</strong>d(wx.EVT_PAINT, self.OnPa<strong>in</strong>t)<br />
self.B<strong>in</strong>d(wx.EVT_LEFT_DOWN, self.OnLeftDown)<br />
def OnPa<strong>in</strong>t(self, evt):<br />
# draw a simple arrow<br />
dc = wx.BufferedPa<strong>in</strong>tDC(self)<br />
dc.SetBackground(wx.Brush(self.GetBackgroundColour()))<br />
dc.Clear()<br />
w, h = dc.GetSize()<br />
y = h/2<br />
dc.SetPen(wx.Pen(“dark blue”, 2))<br />
dc.DrawL<strong>in</strong>e(w/8, y, w-w/8, y)<br />
549 / 565
dc.DrawL<strong>in</strong>e(w-w/8, y, w/2, h/4)<br />
dc.DrawL<strong>in</strong>e(w-w/8, y, w/2, 3*h/4)<br />
def OnLeftDown(self, evt):<br />
text = self.source.GetValue()<br />
data = wx.TextDataObject(text)<br />
dropSource = wx.DropSource(self)#<br />
dropSource.SetData(data)#<br />
result = dropSource.DoDragDrop(wx.Drag_AllowMove)#<br />
# if the user wants to move the data then we should delete it<br />
# from the source<br />
if result == wx.DragMove:<br />
self.source.SetValue(“”)#<br />
class MyFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, title=”Drop Source”)<br />
p = wx.Panel(self)<br />
# create the controls<br />
label1 = wx.StaticText(p, -1, ”Put some text <strong>in</strong> this control:”)<br />
label2 = wx.StaticText(p, -1,<br />
”Then drag from the neighbor<strong>in</strong>g bitmap and\n”<br />
”drop <strong>in</strong> an application that accepts dropped\n”<br />
”text, such as MS Word.”)<br />
text = wx.TextCtrl(p, -1, ”Some text”)<br />
dragctl = DragController(p, text)<br />
# setup the layout with sizers<br />
sizer = wx.BoxSizer(wx.VERTICAL)<br />
sizer.Add(label1, 0, wx.ALL, 5)<br />
hrow = wx.BoxSizer(wx.HORIZONTAL)<br />
hrow.Add(text, 1, wx.RIGHT, 5)<br />
hrow.Add(dragctl, 0)<br />
sizer.Add(hrow, 0, wx.EXPAND|wx.ALL, 5)<br />
sizer.Add(label2, 0, wx.ALL, 5)<br />
p.SetSizer(sizer)<br />
sizer.Fit(self)<br />
550 / 565
app = wx.PySimpleApp()<br />
frm = MyFrame()<br />
frm.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
<br />
<br />
18.3 <br />
<br />
wx.DropSource<br />
wx.DropTarget<br />
wx.W<strong>in</strong>dowSetDropTarget(target)<br />
<br />
wx.W<strong>in</strong>dowwx.W<strong>in</strong>dow<br />
<br />
<br />
wx.DataObjectSetDataObject(data)wx.DataObject<br />
<br />
<br />
GetDataObject()<br />
wx.TextDataObject<br />
class MyDropTarget(wx.DropTarget):<br />
def __<strong>in</strong>it__(self):<br />
self.data = wx.TextDataObject()<br />
self.SetDataObject(data)<br />
target = MyDataTarget()<br />
w<strong>in</strong>.SetDropTarget(target)<br />
18.3.1 <br />
wx.DropTarget<br />
OnData(x, y, default)<br />
x,ydefaultDoDragDrop()<br />
DoDragDrop()<br />
551 / 565
OnData()<br />
GetData()GetData()<br />
GetData()<br />
MyDropTarget.OnData()<br />
<br />
def OnData(self, x, y, default):<br />
self.GetData()<br />
actual_data = self.data.GetText()<br />
# Do someth<strong>in</strong>g with the data here...<br />
return default<br />
OnData()——default<br />
wx.DragNone<br />
OnData()<br />
<br />
<br />
OnData()<br />
DoDragDrop()<br />
wx.DropTargetOn...<br />
OnData()<br />
<br />
OnDrop(x, y)<br />
OnEnter(x, y, default)<br />
OnDragOver(x, y, default)<br />
OnLeave()<br />
x, y, defaultOnData()<br />
<br />
OnEnter()<br />
<br />
defaultwx.DragNone<br />
<strong>wxPython</strong><br />
OnDragOver()<br />
552 / 565
wx.DragNone(drop)OnDrop()<br />
OnData()OnLeave()<br />
<strong>wxPython</strong><br />
wx.DataObject<br />
<br />
wx.TextDropTargetOnDropText(x, y, data)<br />
OnData()x,ydata<br />
<br />
TrueFalse<br />
wx.FileDropTarget<br />
OnDropFiles(x, y, filenames)filenames<br />
TrueFalse<br />
<br />
18.3.2 <br />
18.3<br />
<br />
18.3<br />
18.3<br />
18.3 <br />
#-*- encod<strong>in</strong>g:UTF-8 -*-<br />
import wx<br />
553 / 565
class MyFileDropTarget(wx.FileDropTarget):#<br />
def __<strong>in</strong>it__(self, w<strong>in</strong>dow):<br />
wx.FileDropTarget.__<strong>in</strong>it__(self)<br />
self.w<strong>in</strong>dow = w<strong>in</strong>dow<br />
def OnDropFiles(self, x, y, filenames):#<br />
self.w<strong>in</strong>dow.AppendText(“\n%d file(s) dropped at (%d,%d):\n” %<br />
(len(filenames), x, y))<br />
for file <strong>in</strong> filenames:<br />
self.w<strong>in</strong>dow.AppendText(“\t%s\n” % file)<br />
class MyFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, title=”Drop Target”,<br />
size=(500,300))<br />
p = wx.Panel(self)<br />
# create the controls<br />
label = wx.StaticText(p, -1, ”Drop some files here:”)<br />
text = wx.TextCtrl(p, -1, ””,<br />
style=wx.TE_MULTILINE|wx.HSCROLL)<br />
# setup the layout with sizers<br />
sizer = wx.BoxSizer(wx.VERTICAL)<br />
sizer.Add(label, 0, wx.ALL, 5)<br />
sizer.Add(text, 1, wx.EXPAND|wx.ALL, 5)<br />
p.SetSizer(sizer)<br />
# make the text control be a drop target<br />
dt = MyFileDropTarget(text)#<br />
text.SetDropTarget(dt)<br />
app = wx.PySimpleApp()<br />
frm = MyFrame()<br />
frm.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
554 / 565
<strong>wxPython</strong><br />
<br />
18.4 <br />
<strong>wxPython</strong><br />
<br />
<strong>wxPython</strong><br />
<br />
18.4.1 <br />
<br />
<br />
<br />
<strong>wxPython</strong><br />
RTF<br />
Microsoft Word<br />
<strong>wxPython</strong><br />
wx.CustomDataObjectwx.CustomDataObject<br />
<br />
wx.CustomDataObject(format=wx.FormatInvalid)<br />
formatwx.DataFormat<br />
<strong>wxPython</strong><br />
<br />
SetData(data)<br />
data<br />
<br />
data_object = wx.CustomDataObject(“MyNiftyFormat”)<br />
data = cPickle.dumps(my_object)<br />
data_object.SetData(data)<br />
555 / 565
data_object<br />
<br />
<br />
18.4.2 <br />
<br />
pickle<br />
pickle<br />
data_object = wx.CustomDataObject(“MyNiftyFormat”)<br />
if wx.TheClipboard.Open():<br />
success = wx.TheClipboard.GetData(data_object)<br />
wx.TheClipboard.Close()<br />
if success:<br />
pickled_data = data_object.GetData()<br />
object = cPickle.loads(pickled_data)<br />
pickle<br />
OnData()<br />
pickle<br />
wx.DataObject<br />
wx.PyDataObjectSimple<br />
wx.PyTextDataObjectwx.PyBitmapDataObject, <br />
wx.PyFileDataObject<br />
18.4.3 <br />
<strong>wxPython</strong><br />
<br />
<br />
<br />
wx.DataObjectComposite<br />
wx.DataObjectSimplewx.DataObjectComposite<br />
<br />
<br />
556 / 565
wx.DataObjectComposite()Add(data, preferred=False)<br />
<br />
<br />
data_object = wx.CustomDataObject(“MyNiftyFormat”)<br />
data_object.SetData(cPickle.dumps(my_object))<br />
text_object = wx.TextDataObject(str(my_object))<br />
composite = wx.DataObjectComposite()<br />
composite.Add(data_object)<br />
composite.Add(text_object)<br />
<br />
pickle<br />
<br />
<br />
18.5 wx.Timer<br />
<br />
wx.Timer<br />
18.5.1 EVT_TIMER<br />
wx.TimerEVT_TIMER<br />
<br />
<br />
wx.Timer<br />
<br />
wx.Timer(owner=None, id=-1)<br />
ownerwx.EvtHandler<br />
<strong>wxPython</strong>id<br />
id<strong>wxPython</strong>id<br />
owneridSetOwner(owner=None, id=-1)<br />
<br />
557 / 565
wx.EVT_TIMER<br />
self.B<strong>in</strong>d(wx.EVT_TIMER, self.OnTimerEvent)<br />
B<strong>in</strong>d<br />
ID<br />
timer1 = wx.Timer(self)<br />
timer2 = wx.Timer(self)<br />
self.B<strong>in</strong>d(wx.EVT_TIMER, self.OnTimer1Event, timer1)<br />
self.B<strong>in</strong>d(wx.EVT_TIMER, self.OnTimer2Event, timer2)<br />
<br />
<br />
Start(milliseconds=-1, oneShot=False)milliseconds<br />
millisecondswx.EVT_TIMER<br />
milliseconds=-1oneShotTrue<br />
wx.EVT_TIMER<br />
Stop()<br />
18.4<br />
18.4 <br />
#-*- encod<strong>in</strong>g:UTF-8 -*-<br />
import wx<br />
import time<br />
class ClockW<strong>in</strong>dow(wx.W<strong>in</strong>dow):<br />
def __<strong>in</strong>it__(self, parent):<br />
wx.W<strong>in</strong>dow.__<strong>in</strong>it__(self, parent)<br />
self.B<strong>in</strong>d(wx.EVT_PAINT, self.OnPa<strong>in</strong>t)<br />
self.timer = wx.Timer(self)#<br />
self.B<strong>in</strong>d(wx.EVT_TIMER, self.OnTimer, self.timer)#<br />
self.timer.Start(1000)#<br />
558 / 565
def Draw(self, dc):#<br />
t = time.localtime(time.time())<br />
st = time.strftime(“%I:%M:%S”, t)<br />
w, h = self.GetClientSize()<br />
dc.SetBackground(wx.Brush(self.GetBackgroundColour()))<br />
dc.Clear()<br />
dc.SetFont(wx.Font(30, wx.SWISS, wx.NORMAL, wx.NORMAL))<br />
tw, th = dc.GetTextExtent(st)<br />
dc.DrawText(st, (w-tw)/2, (h)/2 - th/2)<br />
def OnTimer(self, evt):#<br />
dc = wx.BufferedDC(wx.ClientDC(self))<br />
self.Draw(dc)<br />
def OnPa<strong>in</strong>t(self, evt):<br />
dc = wx.BufferedPa<strong>in</strong>tDC(self)<br />
self.Draw(dc)<br />
class MyFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, title=”wx.Timer”)<br />
ClockW<strong>in</strong>dow(self)<br />
app = wx.PySimpleApp()<br />
frm = MyFrame()<br />
frm.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
<br />
IsRunn<strong>in</strong>g()<br />
GetInterval()<br />
IsOneShot()True<br />
wx.TimerEventwx.Event<br />
wx.GetInterval()<br />
<br />
GetId()ID<br />
559 / 565
18.5.2 <br />
wx.Timer<br />
Notify()<br />
<br />
Notify()<br />
wx.FutureCall<br />
<br />
wx.FutureCall(<strong>in</strong>terval, callable, *args, **kwargs)<br />
wx.FutureCall<strong>in</strong>terval<br />
callable*args, **kwargscallable<br />
wx.FutureCall<br />
<strong>wxPython</strong><br />
18.6 <strong>wxPython</strong><br />
GUI<br />
<br />
<strong>wxPython</strong><br />
<br />
GUI<br />
GUI<br />
UnixGUI<br />
W<strong>in</strong>dowsUI<strong>wxPython</strong><br />
<br />
wx.Bitmap<br />
<strong>wxPython</strong>UI<br />
UIGUI<strong>wxPython</strong><br />
<br />
560 / 565
<strong>wxPython</strong><br />
wx.CallAfter()<br />
Python<br />
<br />
18.6.1 wx.CallAfter()<br />
18.5<strong>wxPython</strong><br />
wx.CallAfter()<br />
wx.CallAfter()<br />
wx.CallAfter()<br />
18.4<br />
18.4<br />
18.518.4<br />
18.5 wx.CallAfter()<br />
#-*- encod<strong>in</strong>g:UTF-8 -*-<br />
import wx<br />
import thread<strong>in</strong>g<br />
import random<br />
class WorkerThread(thread<strong>in</strong>g.Thread):<br />
”””<br />
This just simulates some long-runn<strong>in</strong>g task that periodically sends<br />
a message to the GUI thread.<br />
561 / 565
”””<br />
def __<strong>in</strong>it__(self, threadNum, w<strong>in</strong>dow):<br />
thread<strong>in</strong>g.Thread.__<strong>in</strong>it__(self)<br />
self.threadNum = threadNum<br />
self.w<strong>in</strong>dow = w<strong>in</strong>dow<br />
self.timeToQuit = thread<strong>in</strong>g.Event()<br />
self.timeToQuit.clear()<br />
self.messageCount = random.rand<strong>in</strong>t(10,20)<br />
self.messageDelay = 0.1 + 2.0 * random.random()<br />
def stop(self):<br />
self.timeToQuit.set()<br />
def run(self):#<br />
msg = ”Thread %d iterat<strong>in</strong>g %d times with a delay of %1.4f\n” \<br />
% (self.threadNum, self.messageCount, self.messageDelay)<br />
wx.CallAfter(self.w<strong>in</strong>dow.LogMessage, msg)<br />
for i <strong>in</strong> range(1, self.messageCount+1):<br />
self.timeToQuit.wait(self.messageDelay)<br />
if self.timeToQuit.isSet():<br />
break<br />
msg = ”Message %d from thread %d\n” % (i, self.threadNum)<br />
wx.CallAfter(self.w<strong>in</strong>dow.LogMessage, msg)<br />
else:<br />
wx.CallAfter(self.w<strong>in</strong>dow.ThreadF<strong>in</strong>ished, self)<br />
class MyFrame(wx.Frame):<br />
def __<strong>in</strong>it__(self):<br />
wx.Frame.__<strong>in</strong>it__(self, None, title=”Multi-threaded GUI”)<br />
self.threads = []<br />
self.count = 0<br />
panel = wx.Panel(self)<br />
startBtn = wx.Button(panel, -1, ”Start a thread”)<br />
stopBtn = wx.Button(panel, -1, ”Stop all threads”)<br />
self.tc = wx.StaticText(panel, -1, ”Worker Threads: 00”)<br />
self.log = wx.TextCtrl(panel, -1, ””,<br />
562 / 565
style=wx.TE_RICH|wx.TE_MULTILINE)<br />
<strong>in</strong>ner = wx.BoxSizer(wx.HORIZONTAL)<br />
<strong>in</strong>ner.Add(startBtn, 0, wx.RIGHT, 15)<br />
<strong>in</strong>ner.Add(stopBtn, 0, wx.RIGHT, 15)<br />
<strong>in</strong>ner.Add(self.tc, 0, wx.ALIGN_CENTER_VERTICAL)<br />
ma<strong>in</strong> = wx.BoxSizer(wx.VERTICAL)<br />
ma<strong>in</strong>.Add(<strong>in</strong>ner, 0, wx.ALL, 5)<br />
ma<strong>in</strong>.Add(self.log, 1, wx.EXPAND|wx.ALL, 5)<br />
panel.SetSizer(ma<strong>in</strong>)<br />
self.B<strong>in</strong>d(wx.EVT_BUTTON, self.OnStartButton, startBtn)<br />
self.B<strong>in</strong>d(wx.EVT_BUTTON, self.OnStopButton, stopBtn)<br />
self.B<strong>in</strong>d(wx.EVT_CLOSE, self.OnCloseW<strong>in</strong>dow)<br />
self.UpdateCount()<br />
def OnStartButton(self, evt):<br />
self.count += 1<br />
thread = WorkerThread(self.count, self)#<br />
self.threads.append(thread)<br />
self.UpdateCount()<br />
thread.start()#<br />
def OnStopButton(self, evt):<br />
self.StopThreads()<br />
self.UpdateCount()<br />
def OnCloseW<strong>in</strong>dow(self, evt):<br />
self.StopThreads()<br />
self.Destroy()<br />
def StopThreads(self):#<br />
while self.threads:<br />
thread = self.threads[0]<br />
thread.stop()<br />
self.threads.remove(thread)<br />
def UpdateCount(self):<br />
self.tc.SetLabel(“Worker Threads: %d” % len(self.threads))<br />
563 / 565
def LogMessage(self, msg):#<br />
self.log.AppendText(msg)<br />
def ThreadF<strong>in</strong>ished(self, thread):#<br />
self.threads.remove(thread)<br />
self.UpdateCount()<br />
app = wx.PySimpleApp()<br />
frm = MyFrame()<br />
frm.Show()<br />
app.Ma<strong>in</strong>Loop()<br />
Pythonthread<strong>in</strong>g<br />
wx.CallAfter(func,*args)<br />
func(*args)<br />
LogMessage()<br />
ThreadF<strong>in</strong>ished()<br />
18.6.2 <br />
CallAfter()<br />
PythonUI<br />
UIwx.EVT_IDLE<br />
<br />
<br />
<br />
wx.WakeUpIdle()wx.CallAfter()<br />
<br />
GUI<br />
18.6.3 <br />
<strong>wxPython</strong><br />
wx.PostEvent(w<strong>in</strong>dow, event)UI<br />
<br />
wx.WakeUpIdle<strong>wxPython</strong><br />
564 / 565
wx.CallAfter()<br />
<br />
18.7 <br />
1wx.DataObject<br />
<br />
wx.TheClipboard<br />
<br />
2<br />
<br />
3wx.Timer<br />
4<strong>wxPython</strong>GUI<br />
wx.CallAfter()<br />
565 / 565