python画图程序

 

#!/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元组的形式返回设备上下文的像素尺寸。

 

 

 

 

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值