⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pysketch.py

📁 Wxpython Implemented on Windows CE, Source code
💻 PY
📖 第 1 页 / 共 5 页
字号:
""" pySketch

    A simple object-oriented drawing program.

    This is completely free software; please feel free to adapt or use this in
    any way you like.

    Author: Erik Westra (ewestra@wave.co.nz)

    #########################################################################

    NOTE

    pySketch requires wxPython version 2.3.  If you are running an earlier
    version, you need to patch your copy of wxPython to fix a bug which will
    cause the "Edit Text Object" dialog box to crash.

    To patch an earlier version of wxPython, edit the wxPython/windows.py file,
    find the wxPyValidator.__init__ method and change the line which reads:

        self._setSelf(self, wxPyValidator, 0)

    to:

        self._setSelf(self, wxPyValidator, 1)

    This fixes a known bug in wxPython 2.2.5 (and possibly earlier) which has
    now been fixed in wxPython 2.3.

    #########################################################################

    TODO:

      * Add ARGV checking to see if a document was double-clicked on.

    Known Bugs:

      * Scrolling the window causes the drawing panel to be mucked up until you
        refresh it.  I've got no idea why.

      * I suspect that the reference counting for some wxPoint objects is
        getting mucked up; when the user quits, we get errors about being
        unable to call del on a 'None' object.
"""
import sys
import cPickle, os.path
import wx
from wx.lib.buttons import GenBitmapButton


import traceback, types

#----------------------------------------------------------------------------
#                            System Constants
#----------------------------------------------------------------------------

# Our menu item IDs:

menu_UNDO          = 10001 # Edit menu items.
menu_SELECT_ALL    = 10002
menu_DUPLICATE     = 10003
menu_EDIT_TEXT     = 10004
menu_DELETE        = 10005

menu_SELECT        = 10101 # Tools menu items.
menu_LINE          = 10102
menu_RECT          = 10103
menu_ELLIPSE       = 10104
menu_TEXT          = 10105

menu_MOVE_FORWARD  = 10201 # Object menu items.
menu_MOVE_TO_FRONT = 10202
menu_MOVE_BACKWARD = 10203
menu_MOVE_TO_BACK  = 10204

menu_ABOUT         = 10205 # Help menu items.

# Our tool IDs:

id_SELECT  = 11001
id_LINE    = 11002
id_RECT    = 11003
id_ELLIPSE = 11004
id_TEXT    = 11005

# Our tool option IDs:

id_FILL_OPT   = 12001
id_PEN_OPT    = 12002
id_LINE_OPT   = 12003

id_LINESIZE_0 = 13001
id_LINESIZE_1 = 13002
id_LINESIZE_2 = 13003
id_LINESIZE_3 = 13004
id_LINESIZE_4 = 13005
id_LINESIZE_5 = 13006

# DrawObject type IDs:

obj_LINE    = 1
obj_RECT    = 2
obj_ELLIPSE = 3
obj_TEXT    = 4

# Selection handle IDs:

handle_NONE         = 1
handle_TOP_LEFT     = 2
handle_TOP_RIGHT    = 3
handle_BOTTOM_LEFT  = 4
handle_BOTTOM_RIGHT = 5
handle_START_POINT  = 6
handle_END_POINT    = 7

# Dragging operations:

drag_NONE   = 1
drag_RESIZE = 2
drag_MOVE   = 3
drag_DRAG   = 4

# Visual Feedback types:

feedback_LINE    = 1
feedback_RECT    = 2
feedback_ELLIPSE = 3

# Mouse-event action parameter types:

param_RECT = 1
param_LINE = 2

# Size of the drawing page, in pixels.

PAGE_WIDTH  = 1000
PAGE_HEIGHT = 1000

#----------------------------------------------------------------------------

class DrawingFrame(wx.Frame):
    """ A frame showing the contents of a single document. """

    # ==========================================
    # == Initialisation and Window Management ==
    # ==========================================

    def __init__(self, parent, id, title, fileName=None):
        """ Standard constructor.

            'parent', 'id' and 'title' are all passed to the standard wx.Frame
            constructor.  'fileName' is the name and path of a saved file to
            load into this frame, if any.
        """
        wx.Frame.__init__(self, parent, id, title,
                         style = wx.DEFAULT_FRAME_STYLE | wx.WANTS_CHARS |
                                 wx.NO_FULL_REPAINT_ON_RESIZE)

        # Setup our menu bar.

        menuBar = wx.MenuBar()

        self.fileMenu = wx.Menu()
        self.fileMenu.Append(wx.ID_NEW,    "New\tCTRL-N")
        self.fileMenu.Append(wx.ID_OPEN,   "Open...\tCTRL-O")
        self.fileMenu.Append(wx.ID_CLOSE,  "Close\tCTRL-W")
        self.fileMenu.AppendSeparator()
        self.fileMenu.Append(wx.ID_SAVE,   "Save\tCTRL-S")
        self.fileMenu.Append(wx.ID_SAVEAS, "Save As...")
        self.fileMenu.Append(wx.ID_REVERT, "Revert...")
        self.fileMenu.AppendSeparator()
        self.fileMenu.Append(wx.ID_EXIT,   "Quit\tCTRL-Q")

        menuBar.Append(self.fileMenu, "File")

        self.editMenu = wx.Menu()
        self.editMenu.Append(menu_UNDO,          "Undo\tCTRL-Z")
        self.editMenu.AppendSeparator()
        self.editMenu.Append(menu_SELECT_ALL,    "Select All\tCTRL-A")
        self.editMenu.AppendSeparator()
        self.editMenu.Append(menu_DUPLICATE,     "Duplicate\tCTRL-D")
        self.editMenu.Append(menu_EDIT_TEXT,     "Edit...\tCTRL-E")
        self.editMenu.Append(menu_DELETE,        "Delete\tDEL")

        menuBar.Append(self.editMenu, "Edit")

        self.toolsMenu = wx.Menu()
        self.toolsMenu.Append(menu_SELECT,  "Selection", kind=wx.ITEM_CHECK)
        self.toolsMenu.Append(menu_LINE,    "Line",      kind=wx.ITEM_CHECK)
        self.toolsMenu.Append(menu_RECT,    "Rectangle", kind=wx.ITEM_CHECK)
        self.toolsMenu.Append(menu_ELLIPSE, "Ellipse",   kind=wx.ITEM_CHECK)
        self.toolsMenu.Append(menu_TEXT,    "Text",      kind=wx.ITEM_CHECK)

        menuBar.Append(self.toolsMenu, "Tools")

        self.objectMenu = wx.Menu()
        self.objectMenu.Append(menu_MOVE_FORWARD,  "Move Forward")
        self.objectMenu.Append(menu_MOVE_TO_FRONT, "Move to Front\tCTRL-F")
        self.objectMenu.Append(menu_MOVE_BACKWARD, "Move Backward")
        self.objectMenu.Append(menu_MOVE_TO_BACK,  "Move to Back\tCTRL-B")

        menuBar.Append(self.objectMenu, "Object")

        self.helpMenu = wx.Menu()
        self.helpMenu.Append(menu_ABOUT, "About pySketch...")

        menuBar.Append(self.helpMenu, "Help")

        self.SetMenuBar(menuBar)

        # Create our toolbar.

        tsize = (16,16)
        self.toolbar = self.CreateToolBar(wx.TB_HORIZONTAL |
                                          wx.NO_BORDER | wx.TB_FLAT)

        self.toolbar.AddSimpleTool(wx.ID_NEW,
                                   wx.ArtProvider.GetBitmap(wx.ART_NEW, wx.ART_TOOLBAR, tsize),
                                   "New")
        self.toolbar.AddSimpleTool(wx.ID_OPEN,
                                   wx.ArtProvider.GetBitmap(wx.ART_FILE_OPEN, wx.ART_TOOLBAR, tsize),
                                   "Open")
        self.toolbar.AddSimpleTool(wx.ID_SAVE,
                                   wx.ArtProvider.GetBitmap(wx.ART_FILE_SAVE, wx.ART_TOOLBAR, tsize),
                                   "Save")
        self.toolbar.AddSeparator()
        self.toolbar.AddSimpleTool(menu_UNDO,
                                   wx.ArtProvider.GetBitmap(wx.ART_UNDO, wx.ART_TOOLBAR, tsize),
                                   "Undo")
        self.toolbar.AddSeparator()
        self.toolbar.AddSimpleTool(menu_DUPLICATE,
                                   wx.Bitmap("images/duplicate.bmp",
                                            wx.BITMAP_TYPE_BMP),
                                   "Duplicate")
        self.toolbar.AddSeparator()
        self.toolbar.AddSimpleTool(menu_MOVE_FORWARD,
                                   wx.Bitmap("images/moveForward.bmp",
                                            wx.BITMAP_TYPE_BMP),
                                   "Move Forward")
        self.toolbar.AddSimpleTool(menu_MOVE_BACKWARD,
                                   wx.Bitmap("images/moveBack.bmp",
                                            wx.BITMAP_TYPE_BMP),
                                   "Move Backward")

        self.toolbar.Realize()

        # Associate each menu/toolbar item with the method that handles that
        # item.
        menuHandlers = [
        (wx.ID_NEW,    self.doNew),
        (wx.ID_OPEN,   self.doOpen),
        (wx.ID_CLOSE,  self.doClose),
        (wx.ID_SAVE,   self.doSave),
        (wx.ID_SAVEAS, self.doSaveAs),
        (wx.ID_REVERT, self.doRevert),
        (wx.ID_EXIT,   self.doExit),

        (menu_UNDO,          self.doUndo),
        (menu_SELECT_ALL,    self.doSelectAll),
        (menu_DUPLICATE,     self.doDuplicate),
        (menu_EDIT_TEXT,     self.doEditText),
        (menu_DELETE,        self.doDelete),

        (menu_SELECT,  self.doChooseSelectTool),
        (menu_LINE,    self.doChooseLineTool),
        (menu_RECT,    self.doChooseRectTool),
        (menu_ELLIPSE, self.doChooseEllipseTool),
        (menu_TEXT,    self.doChooseTextTool),

        (menu_MOVE_FORWARD,  self.doMoveForward),
        (menu_MOVE_TO_FRONT, self.doMoveToFront),
        (menu_MOVE_BACKWARD, self.doMoveBackward),
        (menu_MOVE_TO_BACK,  self.doMoveToBack),

        (menu_ABOUT, self.doShowAbout)]
        for combo in menuHandlers:
                id, handler = combo
                self.Bind(wx.EVT_MENU, handler, id = id)
                
        
        # Install our own method to handle closing the window.  This allows us
        # to ask the user if he/she wants to save before closing the window, as
        # well as keeping track of which windows are currently open.

        self.Bind(wx.EVT_CLOSE, self.doClose)

        # Install our own method for handling keystrokes.  We use this to let
        # the user move the selected object(s) around using the arrow keys.

        self.Bind(wx.EVT_CHAR_HOOK, self.onKeyEvent)

        # Setup our top-most panel.  This holds the entire contents of the
        # window, excluding the menu bar.

        self.topPanel = wx.Panel(self, -1, style=wx.SIMPLE_BORDER)

        # Setup our tool palette, with all our drawing tools and option icons.

        self.toolPalette = wx.BoxSizer(wx.VERTICAL)

        self.selectIcon  = ToolPaletteIcon(self.topPanel, id_SELECT,
                                           "select", "Selection Tool")
        self.lineIcon    = ToolPaletteIcon(self.topPanel, id_LINE,
                                           "line", "Line Tool")
        self.rectIcon    = ToolPaletteIcon(self.topPanel, id_RECT,
                                           "rect", "Rectangle Tool")
        self.ellipseIcon = ToolPaletteIcon(self.topPanel, id_ELLIPSE,
                                           "ellipse", "Ellipse Tool")
        self.textIcon    = ToolPaletteIcon(self.topPanel, id_TEXT,
                                           "text", "Text Tool")

        toolSizer = wx.GridSizer(0, 2, 5, 5)
        toolSizer.Add(self.selectIcon)
        toolSizer.Add((0, 0)) # Gap to make tool icons line up nicely.
        toolSizer.Add(self.lineIcon)
        toolSizer.Add(self.rectIcon)
        toolSizer.Add(self.ellipseIcon)
        toolSizer.Add(self.textIcon)

        self.optionIndicator = ToolOptionIndicator(self.topPanel)
        self.optionIndicator.SetToolTip(
                wx.ToolTip("Shows Current Pen/Fill/Line Size Settings"))

        optionSizer = wx.BoxSizer(wx.HORIZONTAL)

        self.penOptIcon  = ToolPaletteIcon(self.topPanel, id_PEN_OPT,
                                           "penOpt", "Set Pen Colour")
        self.fillOptIcon = ToolPaletteIcon(self.topPanel, id_FILL_OPT,
                                           "fillOpt", "Set Fill Colour")
        self.lineOptIcon = ToolPaletteIcon(self.topPanel, id_LINE_OPT,
                                           "lineOpt", "Set Line Size")

        margin = wx.LEFT | wx.RIGHT
        optionSizer.Add(self.penOptIcon,  0, margin, 1)
        optionSizer.Add(self.fillOptIcon, 0, margin, 1)
        optionSizer.Add(self.lineOptIcon, 0, margin, 1)

        margin = wx.TOP | wx.LEFT | wx.RIGHT | wx.ALIGN_CENTRE
        self.toolPalette.Add(toolSizer,            0, margin, 5)
        self.toolPalette.Add((0, 0),               0, margin, 5) # Spacer.
        self.toolPalette.Add(self.optionIndicator, 0, margin, 5)
        self.toolPalette.Add(optionSizer,          0, margin, 5)

        # Make the tool palette icons respond when the user clicks on them.

        self.selectIcon.Bind(wx.EVT_BUTTON, self.onToolIconClick)
        self.lineIcon.Bind(wx.EVT_BUTTON, self.onToolIconClick)
        self.rectIcon.Bind(wx.EVT_BUTTON, self.onToolIconClick)
        self.ellipseIcon.Bind(wx.EVT_BUTTON, self.onToolIconClick)
        self.textIcon.Bind(wx.EVT_BUTTON, self.onToolIconClick)
        self.penOptIcon.Bind(wx.EVT_BUTTON, self.onPenOptionIconClick)
        self.fillOptIcon.Bind(wx.EVT_BUTTON, self.onFillOptionIconClick)
        self.lineOptIcon.Bind(wx.EVT_BUTTON, self.onLineOptionIconClick)

        # Setup the main drawing area.

        self.drawPanel = wx.ScrolledWindow(self.topPanel, -1,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -