21.01.2015 Views

wxPython in Action - 错误提示:发生了异常

wxPython in Action - 错误提示:发生了异常

wxPython in Action - 错误提示:发生了异常

SHOW MORE
SHOW LESS

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

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!