#!/usr/bin/python
# -*- coding: utf-8 -*
import wx
import wx.lib.buttons as buttons
import wx.adv as adv
import wx.lib.colourselect as color
import wx.html
import os
import pickle
import math
class ControlPanel(wx.Panel):
BMP_SIZE = 16
BMP_BORDER = 3
NUM_COLS = 4
SPACING = 4
colorList = ('Black', 'Yellow', 'Red', 'Green', 'Blue',
'Purple', 'Brown', 'Aquamarine', 'Forest Green',
'Light Blue', 'Goldenrod', 'Cyan',
'Orange', 'Navy', 'Dark Grey', 'Light Grey')
maxThickness = 16
def __init__(self, parent, ID, sketch):
wx.Panel.__init__(self, parent, ID, style=wx.RAISED_BORDER)
self.sketch = sketch
buttonSize = (self.BMP_SIZE + 2 * self.BMP_BORDER,
self.BMP_SIZE + 2 * self.BMP_BORDER)
colorGrid = self.createColorGrid(parent, buttonSize)
thicknessGrid = self.createThicknessGrid(buttonSize)
self.layout(colorGrid, thicknessGrid)
def createColorGrid(self, parent, buttonSize): # 1 创建颜色网格
self.colorMap = {}
self.colorButtons = {}
colorGrid = wx.GridSizer(cols=self.NUM_COLS, hgap=2, vgap=2)
for eachColor in self.colorList:
bmp = parent.MakeBitmap(eachColor)
b = buttons.GenBitmapToggleButton(self, -1, bmp, size=buttonSize)
b.SetBezelWidth(1)
b.SetUseFocusIndicator(False)
self.Bind(wx.EVT_BUTTON, self.OnSetColour, b)
colorGrid.Add(b, 0)
self.colorMap[b.GetId()] = eachColor
self.colorButtons[eachColor] = b
self.colorButtons[self.colorList[0]].SetToggle(True)
return colorGrid
def createThicknessGrid(self, buttonSize): # 2 创建线条粗细网格
self.thicknessIdMap = {}
self.thicknessButtons = {}
thicknessGrid = wx.GridSizer(cols=self.NUM_COLS, hgap=2, vgap=2)
for x in range(1, self.maxThickness + 1):
b = buttons.GenToggleButton(self, -1, str(x), size=buttonSize)
b.SetBezelWidth(1)
b.SetUseFocusIndicator(False)
self.Bind(wx.EVT_BUTTON, self.OnSetThickness, b)
thicknessGrid.Add(b, 0)
self.thicknessIdMap[b.GetId()] = x
self.thicknessButtons[x] = b
self.thicknessButtons[1].SetToggle(True)
return thicknessGrid
def layout(self, colorGrid, thicknessGrid): # 3 合并网格
box = wx.BoxSizer(wx.VERTICAL)
box.Add(colorGrid, 0, wx.ALL, self.SPACING)
box.Add(thicknessGrid, 0, wx.ALL, self.SPACING)
self.SetSizer(box)
box.Fit(self)
def OnSetColour(self, event):
color = self.colorMap[event.GetId()]
if color != self.sketch.color:
self.colorButtons[self.sketch.color].SetToggle(False)
self.sketch.SetColor(color)
def OnSetThickness(self, event):
thickness = self.thicknessIdMap[event.GetId()]
if thickness != self.sketch.thickness:
self.thicknessButtons[self.sketch.thickness].SetToggle(False)
self.sketch.SetThickness(thickness)
class SketchAbout(wx.Dialog):
text = '''
<html>
<body bgcolor="#ACAA60">
<center>
<table bgcolor="#455481" width="100%" cellspacing="0" cellpadding="0" border="1">
<tr>
<td align="center">
<h1>Sketch!</h1>
</td>
</tr>
</table>
</center>
<p>
<b>Sketch</b> is a demonstration program for <b>wxPython In Action</b>
Chapter 7. It is based on the SuperDoodle demo included with wxPython,
available at http://www.wxpython.org/
</p>
<p><b>SuperDoodle</b> and <b>wxPython</b> are brought to you by
<b>Robin Dunn</b> and <b>Total Control Software</b>, Copyright
? 1997-2006.
</p>
</body>
</html>
'''
def __init__(self, parent):
wx.Dialog.__init__(self, parent, -1, 'About Sketch', size=(440, 400))
html = wx.html.HtmlWindow(self)
html.SetPage(self.text)
button = wx.Button(self, wx.ID_OK, "Okay")
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(html, 1, wx.EXPAND | wx.ALL, 5)
sizer.Add(button, 0, wx.ALIGN_CENTER | wx.ALL, 5)
self.SetSizer(sizer)
self.Layout()
class SketchWindow(wx.Window):
def __init__(self, parent, ID):
wx.Window.__init__(self, parent, ID)
self.SetBackgroundColour("White")
self.color = "Black"
self.thickness = 2
self.pen = wx.Pen(self.color, self.thickness, wx.SOLID)
self.lines = []
self.curLine = []
self.pos = (0, 0)
self.InitBuffer()
# 绑定时间
self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
self.Bind(wx.EVT_MOTION, self.OnMotion)
self.Bind(wx.EVT_SIZE, self.OnSize)
self.Bind(wx.EVT_IDLE, self.OnIdle)
self.Bind(wx.EVT_PAINT, self.OnPaint)
def InitBuffer(self):
size = self.GetClientSize()
# 创建一个缓存的设备上下文
self.buffer = wx.Bitmap(size.width, size.height)
dc = wx.BufferedDC(None, self.buffer)
# use device content
dc.SetBackground(wx.Brush(self.GetBackgroundColour()))
dc.Clear()
self.DrawLines(dc)
self.reInitBuffer = False
def GetLinesData(self):
return self.lines[:]
def SetLinesData(self, lines):
self.lines = lines[:]
self.InitBuffer()
self.Refresh()
def OnLeftDown(self, event):
self.curLine = []
self.pos = tuple(event.GetPosition())
self.CaptureMouse()
def OnLeftUp(self, event):
if self.HasCapture():
self.lines.append((self.color, self.thickness, self.curLine))
# newPos = tuple(event.GetPosition())
# dc = wx.ClientDC(self)
# dc.DrawCircle(self.pos[0],self.pos[1], math.sqrt(math.pow(self.pos[0]-newPos[0],2)+pow(self.pos[1]-newPos[1],2)))
self.curLine = []
self.ReleaseMouse()
def OnMotion(self, event):
if event.Dragging() and event.LeftIsDown():
dc = wx.BufferedDC(wx.ClientDC(self), self.buffer)
self.drawMotion(dc, event)
event.Skip()
def drawMotion(self, dc, event):
dc.SetPen(self.pen)
newPos = tuple(event.GetPosition())
coords = self.pos + newPos
self.curLine.append(coords)
self.pos = newPos
dc.DrawLine(*coords)
def OnSize(self, event):
self.reInitBuffer = True
def OnIdle(self, event):
if self.reInitBuffer:
self.InitBuffer()
self.Refresh(False)
def OnPaint(self, event):
dc = wx.BufferedPaintDC(self, self.buffer)
self.DrawLines(dc)
def DrawLines(self, dc):
for colour, thickness, line in self.lines:
pen = wx.Pen(colour, self.thickness, wx.SOLID)
dc.SetPen(pen)
for coords in line:
dc.DrawLine(*coords)
def SetColor(self, color):
self.color = color
self.pen = wx.Pen(self.color, self.thickness, wx.SOLID)
def SetThickness(self, num):
self.thickness = num
self.pen = wx.Pen(self.color, self.thickness, wx.SOLID)
class SketchFrame(wx.Frame):
def __init__(self, parent):
self.title = "Sketch Frame"
wx.Frame.__init__(self, parent, -1, self.title, size=(800, 600))
self.filename = ""
self.wildcard = "Sketch files(*.sketch)|*.sketch|Text files(*.txt)|*.txt|All files (*.*)|*.*"
self.sketch = SketchWindow(self, -1)
self.sketch.Bind(wx.EVT_MOTION, self.OnSketchMotion)
self.createToolBar()#创建工具栏
self.initStatusBar()#初始化状态栏
self.createMenuBar()#创建菜单栏
self.createPanel()#创建颜色面板
def createToolBar(self): # 1创建工具栏
toolbar = self.CreateToolBar()
# toolbar.AddSimpleTool(1, wx.Image('new.png', wx.BITMAP_TYPE_PNG).ConvertToBitmap(), 'New', '')
# toolbar.AddSimpleTool(2, wx.Image('open.png', wx.BITMAP_TYPE_PNG).ConvertToBitmap(), 'Opne', '')
# toolbar.AddSimpleTool(3, wx.Image('save.png', wx.BITMAP_TYPE_PNG).ConvertToBitmap(), 'Save', '')
# toolbar.AddSimpleTool(1, wx.Image('new.bmp', wx.BITMAP_TYPE_BMP).ConvertToBitmap(), 'New', '')
# toolbar.AddSimpleTool(2, wx.Image('open.bmp', wx.BITMAP_TYPE_BMP).ConvertToBitmap(), 'Opne', '')
# toolbar.AddSimpleTool(3, wx.Image('save.bmp', wx.BITMAP_TYPE_BMP).ConvertToBitmap(), 'Save', '')
for each in self.toolbarData():
self.createSimpleTool(toolbar, *each)
toolbar.AddSeparator()
# for each in self.toolbarColorData():
# self.createColorTool(toolbar, each)
toolbar.Realize() # 2 显现工具栏
def createSimpleTool(self, toolbar, label, filename, help, handler): # 3 创建常规工具
if not label:
toolbar.AddSeparator()
return
bmp = wx.Image(filename,wx.BITMAP_TYPE_PNG).ConvertToBitmap()
tool = toolbar.AddSimpleTool(-1, bmp, label, help)
self.Bind(wx.EVT_MENU, handler, tool)
def toolbarData(self):
return (("New", "new.png", "Create new sketch",
self.OnNew),
("", "", "", ""),
("Open", "open.png", "Open existing sketch",
self.OnOpen),
("Save", "save.png", "Save existing sketch",
self.OnSave))
def createColorTool(self, toolbar, color): # 4 创建颜色工具
bmp = self.MakeBitmap(color)
newId = wx.NewId()
tool = toolbar.AddRadioTool(newId, bmp.ConvertToBitmap(), shortHelp=color)
self.Bind(wx.EVT_MENU, self.OnColor, tool)
def MakeBitmap(self, color): # 5 创建纯色的位图
bmp = wx.Bitmap(16, 15)
dc = wx.MemoryDC()
dc.SelectObject(bmp)
dc.SetBackground(wx.Brush(color))
dc.Clear()
dc.SelectObject(wx.NullBitmap)
return bmp
def toolbarColorData(self):
return ("Black", "Red", "Green", "Blue")
def createPanel(self):
controlPanel = ControlPanel(self, -1, self.sketch)
box = wx.BoxSizer(wx.HORIZONTAL)
box.Add(controlPanel, 0, wx.EXPAND) # 控制面板在水平方向上不改变
box.Add(self.sketch, 1, wx.EXPAND) # 窗口在水平方向上改变
# box.SetSizeHints(self)
self.SetSizer(box)
def initStatusBar(self):
self.statusBar = self.CreateStatusBar()
self.statusBar.SetFieldsCount(3)
#print("Fields=%d" % self.statusBar.GetFieldsCount())
self.statusBar.SetStatusWidths([-1, -2, -3])
self.statusBar.SetStatusText('画线程序', 1)
def menuData(self): # 2 菜单数据
return [("&File", (
("&New", "New Sketch file", self.OnNew),
("&Open", "Open sketch file", self.OnOpen),
("&Save", "Save sketch file", self.OnSave),
("", "", ""),
("&Color", (
("&Black", "", self.OnColor, wx.ITEM_RADIO),
("&Red", "", self.OnColor, wx.ITEM_RADIO),
("&Green", "", self.OnColor, wx.ITEM_RADIO),
("&Blue", "", self.OnColor, wx.ITEM_RADIO),
("&Other...", "", self.OnOtherColor, wx.ITEM_RADIO),
)),
("", "", ""),
("&Quit", "Quit", self.OnCloseWindow))),
("&Edit", (
("&Copy", "copy Sketch edit", self.OnCopy),
("&Cut", "Cut Sketch edit", self.OnCut),
("&About", "About Sketch edit", self.OnAbout),
))]
def createMenuBar(self):
menuBar = wx.MenuBar()
for eachMenuData in self.menuData():
menuLabel = eachMenuData[0]
menuItems = eachMenuData[1]
menuBar.Append(self.createMenu(menuItems), menuLabel)
self.SetMenuBar(menuBar)
def createMenu(self, menuData):
menu = wx.Menu()
# 3 创建子菜单
for eachItem in menuData:
if len(eachItem) == 2:
label = eachItem[0]
subMenu = self.createMenu(eachItem[1])
menu.Append(wx.NewId(), label, subMenu)
else:
self.createMenuItem(menu, *eachItem)
return menu
def createMenuItem(self, menu, label, status, handler, kind=wx.ITEM_NORMAL):
if not label:
menu.AppendSeparator()
return
menuItem = menu.Append(-1, label, status, kind) # 4 使用kind创建菜单项
self.Bind(wx.EVT_MENU, handler, menuItem)
def SaveFile(self): # 保存文件
if self.filename:
data = self.sketch.GetLinesData()
f = open(self.filename, 'wb')
pickle.dump(data, f, 2) # 数据序列化
f.close()
def ReadFile(self):
try:
f = open(self.filename, 'rb')
data = pickle.load(f) # 数字反序列化
f.close();
self.sketch.SetLinesData(data)
except pickle.UnpicklingError:
wx.MessageDialog("%s is not a sketch file" % (self.filename, "opps!"),
style=wx.OK | wx.ICON_EXCLAMATION)
def OnCopy(self, event):
pass
def OnCut(self, event):
pass
def OnNew(self, event):
pass
def OnAbout(self, event):
about = SketchAbout(self)
about.ShowModal()
about.Destroy()
def OnOpen(self, event):
dlg = wx.FileDialog(self, "Open sketch file...",
os.getcwd(),
style=wx.FD_OPEN,
wildcard=self.wildcard)
if dlg.ShowModal() == wx.ID_OK:
self.filename = dlg.GetPath()
self.ReadFile()
self.SetTitle(self.title + "--" + self.filename)
dlg.Destroy()
def OnSave(self, event):
if not self.filename:
self.OnSaveAs(event)
else:
self.SaveFile()
def OnSaveAs(self, event): # 弹出保存对话框
dlg = wx.FileDialog(self, "Save sketh as ...",
os.getcwd(),
style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT,
wildcard=self.wildcard)
if dlg.ShowModal() == wx.ID_OK:
filename = dlg.GetPath()
if not os.path.splitext(filename)[1]:
filename = filename + '.sketch'
self.filename = filename
self.SaveFile()
self.SetTitle(self.title + '--' + self.filename)
dlg.Destroy()
def OnColor(self, event): # 5 处理颜色的改变
menubar = self.GetMenuBar()
itemId = event.GetId()
item = menubar.FindItemById(itemId)
if not item:
toolbar = self.GetToolBar()
item = toolbar.FindById(itemId)
color = item.GetShortHelp()
else:
color = item.GetLabel()
self.sketch.SetColor(color)
def OnOtherColor(self, event):
data = wx.ColourData()
data.SetChooseFull(True)
for i in range(16):
colour = wx.Colour(i * 16, i * 16, i * 16)
data.SetCustomColour(i, colour)
dialog = wx.ColourDialog(self, data)
if dialog.ShowModal() == wx.ID_OK:
retData = dialog.GetColourData()
self.sketch.SetColor(retData.GetColour())
def OnCloseWindow(self, event):
self.Destroy()
def OnSketchMotion(self, event):
self.statusBar.SetStatusText("pos:%s" % (str(event.GetPosition())), 0)
self.statusBar.SetStatusText("Current Pts: %s" % (len(self.sketch.curLine)), 1)
self.statusBar.SetStatusText("Line Count: %s" % (len(self.sketch.lines)), 2)
event.Skip()
class SketchApp(wx.App):
def OnInit(self):
bmp = wx.Image("splash.png").ConvertToBitmap()
adv.SplashScreen(bmp, adv.SPLASH_CENTER_ON_SCREEN | adv.SPLASH_TIMEOUT, 1000, None, -1)
wx.Yield()
frame = SketchFrame(None)
frame.Show()
self.SetTopWindow(frame)
return True
if __name__ == '__main__':
app = wx.App()
#SketchApp()
bmp = wx.Image("splash.png").ConvertToBitmap()
adv.SplashScreen(bmp, adv.SPLASH_CENTER_ON_SCREEN | adv.SPLASH_TIMEOUT, 1000, None, id=-1,size=(800,600))
wx.Yield()
frm = SketchFrame(None)
frm.Show()
app.MainLoop()
#画圆弧 DrawArc(x1, y1, x2, y2,xc, yc)
#画圆 DrawCircle(x,y.radius)或 DrawCircle(point,radius)
#画矩形 DrawRectangle(x,y,width,height) 左上角是(x,y),其宽和高是width和 height
#画椭圆 DrawEllipse
画图标: DrawIcon(icon,x,y)
#画线: DrawLine(x1,y1,x2,y2)
#画连接线 DrawLines()该方法以wx.Point对象的一个Python列表为参数,并将其中的点连接起来
#画多边形 DrawPolygon(points) 按给定的wx.Point对象的一个Python列表回执一个多边形
#画字符串DrawText(text,x,y) 从(x,y)开始绘制给定的字符串,使用当前的字体。相关的函数包括D让我RotateDText()和GetTextExtent().
#区域填充 FloodFill(x, y, color,style):从点(x, y)执行一个区域填充,使用当前画刷的颜色。参数style是可选的。style的默认值是wx.FLOOD_SURFACE,它表示当填充碰到另一颜色时停止。另一值wx.FLOOD_BORDER表示参数color是填充的边界,当填充碰到该颜色的代表的边界时停止。
GetBackground() SetBackground(brush):背景画刷是一个wx.Brush对象,当Clear()方法被调用时使用。
GetBrush() SetBrush(brush):画刷是一个wx.Brush对象并且用于填充任何绘制在设备上下文上的形状。
GetFont() SetFont(font):字体(font)是一个wx.Font对象,被用于所有的文本绘制操作。
GetPen() SetPen(pen):画笔(pen)是一个wx.Pen对象,被用于所有绘制线条的操作。
GetPixel(x, y):返回一个关于点(x, y)的像素的一个wx.Colour对象。
GetSize()
GetSizeTuple():以一个wx.Size对象或一个Python元组的形式返回设备上下文的像素尺寸。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)