Advertisement
here2share

# basic_drawing_app.py

Nov 1st, 2016
187
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 14.39 KB | None | 0 0
  1. # basic_drawing_app.py
  2.  
  3. from Tkinter import *
  4. import tkFont
  5.  
  6. #A standard message box
  7. from tkMessageBox import askokcancel
  8. from tkColorChooser import askcolor
  9.  
  10. NORMAL_COLOUR = 'grey90'
  11. SELECTED_COLOUR = 'grey80'
  12.  
  13. # You can think of the toolbar (or probably anything that inherits from a Frame) as a widget
  14.  
  15. class Toolbar(Frame):
  16.     """The toolbar for DrawingApp"""
  17.  
  18.     def __init__(self, master, parent):
  19.         """Create the toolbar:
  20.        master - the toplevel window
  21.        parent - the app object
  22.        """
  23.        
  24.         Frame.__init__(self, master)
  25.         self.parent = parent
  26.         self.rect = Button(self, text="Rectangle", command = self.set_rect,
  27.                            bg = SELECTED_COLOUR)
  28.         self.rect.pack(side=LEFT,padx=2, pady=2)
  29.         self.oval = Button(self, text="Oval", command = self.set_oval,
  30.                            bg = NORMAL_COLOUR)
  31.         self.oval.pack(side=LEFT,padx=2, pady=2)
  32.         self.polygon = Button(self, text="Polygon", command = self.set_poly,
  33.                            bg = NORMAL_COLOUR)
  34.         self.polygon.pack(side=LEFT,padx=2, pady=2)
  35.         self.line = Button(self, text="Line", command = self.set_line,
  36.                            bg = NORMAL_COLOUR)
  37.         self.line.pack(side=LEFT,padx=2, pady=2)
  38.         self.text = Button(self, text="Text", command = self.set_text,
  39.                            bg = NORMAL_COLOUR)
  40.         self.text.pack(side=LEFT,padx=2, pady=2)
  41.         self.move = Button(self, text="Move", command = self.set_move,
  42.                            bg = NORMAL_COLOUR)
  43.         self.move.pack(side=LEFT,padx=2, pady=2)
  44.         self.deletebutton = Button(self, text="Delete",
  45.                                    command = self.set_delete,
  46.                            bg = NORMAL_COLOUR)
  47.         self.deletebutton.pack(side=LEFT,padx=2, pady=2)
  48.         self.selected = self.rect
  49.  
  50.     def change_selected(self, button):
  51.         """Change button colours for change of selection."""
  52.         self.selected.config(bg=NORMAL_COLOUR)
  53.         button.config(bg=SELECTED_COLOUR)
  54.         self.selected=button
  55.        
  56.     def set_rect(self):
  57.         """Set the rectangle selection."""
  58.         self.change_selected(self.rect)
  59.         self.parent.set_rect()
  60.                              
  61.     def set_oval(self):
  62.         """Set the oval selection."""
  63.         self.change_selected(self.oval)
  64.         self.parent.set_oval()
  65.                              
  66.     def set_poly(self):
  67.         """Set the polygon selection."""
  68.         self.change_selected(self.polygon)
  69.         self.parent.set_poly()
  70.        
  71.     def set_line(self):
  72.         """Set the polyline selection."""
  73.         self.change_selected(self.line)
  74.         self.parent.set_line()
  75.  
  76.     def set_text(self):
  77.         """Set the text selection."""
  78.         self.change_selected(self.text)
  79.         self.parent.set_text()
  80.  
  81.     def set_move(self):
  82.         """Set the move selection."""
  83.         self.change_selected(self.move)
  84.         self.parent.set_move()
  85.  
  86.     def set_delete(self):
  87.         """Set the delete selection."""
  88.         self.change_selected(self.deletebutton)
  89.         self.parent.set_delete()
  90.                              
  91.  
  92.                              
  93. # Another widget
  94.  
  95. class Configuration(Frame):
  96.     """The configurations bar for DrawingApp"""
  97.    
  98.     def __init__(self, master):
  99.         """Create the configuration bar:
  100.        master - the toplevel window
  101.        """
  102.        
  103.         Frame.__init__(self, master)
  104.         self.fillc = Button(self, text="Pick Fill Colour",
  105.                             command = self.sef_fill_colour, bg="white")
  106.         self.fillc.pack(side=LEFT,padx=2, pady=2)
  107.         self.outc = Button(self, text="Pick Outline Colour",
  108.                            command = self.set_outline_colour, bg = "white")
  109.         self.outc.pack(side=LEFT,padx=2, pady=2)
  110.         self.linec = Button(self, text="Pick Line Colour",
  111.                             command = self.set_line_colour, bg = "white")
  112.         self.textc = Button(self, text="Pick Text Colour",
  113.                             command = self.set_text_colour, bg = "white")
  114.         self.line_width_label = Label(self,text="Line width: ")
  115.         self.line_width_scale = \
  116.             Spinbox(self, from_=1,to=50,width = 5,
  117.                     command = self.set_line_width, state=DISABLED)
  118.         self.line_width_scale.bind("<Return>", self.set_line_width_return)
  119.         self.current_configs = [self.fillc, self.outc]
  120.         self.line_colour = 'white'
  121.         self.fill_colour = 'white'
  122.         self.text_colour = 'white'
  123.         self.line_width = 1
  124.    
  125.     def set_configs(self, items):
  126.         """Disable widgets for previous config and enable widgets for new
  127.        config items is the list of new widgets."""
  128.  
  129.         if self.line_width_scale in self.current_configs:
  130.             self.line_width_scale.configure(state=DISABLED)
  131.         for b in self.current_configs: b.pack_forget()
  132.         for i in items:
  133.             i.pack(side=LEFT,padx=2, pady=2)
  134.         self.current_configs = items
  135.  
  136.     def set_fill_configs(self):
  137.         """Set the config widgets for rectangles, ovals and polygons."""
  138.         self.set_configs([self.fillc, self.outc])
  139.  
  140.     def set_text_configs(self):
  141.         """Set the text config widgets"""
  142.         self.set_configs([self.textc])
  143.  
  144.     def set_line_configs(self):
  145.         """Set the line config widgets"""
  146.         self.set_configs([self.linec,self.line_width_label,
  147.                          self.line_width_scale])
  148.         self.line_width_scale.configure(state=NORMAL)
  149.  
  150.     def hide_configs(self):
  151.         """Hide all config widgets."""
  152.         self.set_configs([])
  153.  
  154.     def sef_fill_colour(self):
  155.         """Choose fill colour."""
  156.         _, colour = askcolor(self.fill_colour, title="Choose Fill Colour")
  157.         if colour:
  158.             self.fill_colour = colour
  159.             self.fillc.configure(bg= colour)
  160.            
  161.     def set_outline_colour(self):
  162.         """Choose outline colour."""
  163.         _, colour = askcolor(self.line_colour, title="Choose Outline Colour")
  164.         if colour:
  165.             self.line_colour = colour
  166.             self.outc.configure(bg= colour)
  167.             self.linec.configure(bg= colour)
  168.            
  169.     def set_line_colour(self):
  170.         """Choose line colour"""
  171.         _, colour = askcolor(self.line_colour, title="Choose Line Colour")
  172.         if colour:
  173.             self.line_colour = colour
  174.             self.outc.configure(bg= colour)
  175.             self.linec.configure(bg= colour)
  176.  
  177.     def set_text_colour(self):
  178.         """Choose text colour."""
  179.         _, colour = askcolor(self.text_colour, title="Choose Text Colour")
  180.         if colour:
  181.             self.text_colour = colour
  182.             self.textc.configure(bg= colour)
  183.  
  184.     def set_line_width(self):
  185.         self.line_width = self.line_width_scale.get()
  186.  
  187.     def set_line_width_return(self,e):
  188.         self.line_width = self.line_width_scale.get()
  189.  
  190.     def get_fill_colour(self):
  191.         return self.fill_colour
  192.  
  193.     def get_line_colour(self):
  194.         return self.line_colour
  195.  
  196.     def get_text_colour(self):
  197.         return self.text_colour
  198.  
  199.     def get_line_width(self):
  200.         return self.line_width
  201.  
  202.  
  203. # For drawing rectangles and ellipses - left click, drag, release
  204. # For drawing polygons and (poly)lines left click and release to set a point
  205. #    - each subsequent left click/release draws a line from previous point
  206. #    - middle click to end drawing
  207. # For move left click, drag, release
  208. # For delete left click/release
  209.            
  210. class DrawingApp(object):
  211.     """Drawing demo."""
  212.  
  213.     def __init__(self, master=None):
  214.         master.title("Drawing Demo")
  215.         self._master = master
  216.         self.customFont = tkFont.Font(family="Helvetica", size=14)
  217.  
  218.         # Make a toolbar
  219.         toolbar = Toolbar(master, self)
  220.         toolbar.pack(fill=X)
  221.         # Make a canvas and set callbacks
  222.         self.canvas = Canvas(master,width=800, height=600, bg='black')
  223.         self.canvas.pack()
  224.         self.canvas.bind("<Button-1>", self.press_button1)
  225.         self.canvas.bind("<Button-3>", self.press_button3)
  226.         self.canvas.bind("<ButtonRelease-1>", self.releaseButton1)
  227.         self.canvas.bind("<B1-Motion>", self.b1Motion)
  228.         self.canvas.bind("<Motion>", self.motion)
  229.         self.canvas.bind_all("<Key>", self.keypress)
  230.  
  231.         # Make a configuration bar
  232.         self.configFrame = Configuration(master)
  233.         self.configFrame.pack(fill=X)
  234.         self.drawing_fun = self.canvas.create_rectangle
  235.         self.reset()
  236.  
  237.     def reset(self):
  238.         """Reset values ready for next drawing."""
  239.         self.drawing = None
  240.         self.points = []
  241.         self.string = ''
  242.        
  243.  
  244.     def set_rect(self):
  245.         """Set up for drawing rectangles"""
  246.         if self.drawing_fun != self.canvas.create_rectangle:
  247.             self.configFrame.set_fill_configs()
  248.             self.drawing_fun = self.canvas.create_rectangle
  249.         self.reset()
  250.  
  251.     def set_oval(self):
  252.         """Set up for drawing ovals"""
  253.         if self.drawing_fun != self.canvas.create_oval:
  254.             self.configFrame.set_fill_configs()
  255.             self.drawing_fun = self.canvas.create_oval
  256.         self.reset()
  257.  
  258.     def set_poly(self):
  259.         """Set up for drawing polygons"""
  260.         if self.drawing_fun != self.canvas.create_polygon:
  261.             self.configFrame.set_fill_configs()
  262.             self.drawing_fun = self.canvas.create_polygon
  263.         self.reset()
  264.  
  265.     def set_line(self):
  266.         """Set up for drawing polylines"""
  267.         if self.drawing_fun != self.canvas.create_line:
  268.             self.configFrame.set_line_configs()
  269.             self.drawing_fun = self.canvas.create_line
  270.         self.reset()
  271.  
  272.     def set_text(self):
  273.         """Set up for drawing text"""
  274.         if self.drawing_fun != self.canvas.create_text:
  275.             self.configFrame.set_text_configs()
  276.             self.drawing_fun = self.canvas.create_text
  277.         self.reset()
  278.  
  279.     def set_move(self):
  280.         """Set up for moving"""
  281.         if self.drawing_fun not in [self.canvas.move, self.canvas.delete]:
  282.             self.configFrame.hide_configs()
  283.         self.drawing_fun = self.canvas.move
  284.  
  285.     def set_delete(self):
  286.         """Set up for deleting"""
  287.         if self.drawing_fun not in [self.canvas.move, self.canvas.delete]:
  288.             self.configFrame.hide_configs()
  289.         self.drawing_fun = self.canvas.delete
  290.  
  291.     def press_button1(self, e):
  292.         """Left button is pressed"""
  293.         # Drawing rectangles and ovals
  294.         if self.drawing_fun in \
  295.                [self.canvas.create_rectangle,self.canvas.create_oval]:
  296.             self.startx = e.x
  297.             self.starty = e.y
  298.             self.drawing = \
  299.                 self.drawing_fun(e.x, e.y, e.x, e.y,
  300.                                  outline = self.configFrame.get_line_colour(),
  301.                                  fill = self.configFrame.get_fill_colour())
  302.         # Drawing polygons and polylines
  303.         elif self.drawing_fun in \
  304.                 [self.canvas.create_polygon, self.canvas.create_line]:
  305.             self.points.extend([e.x,e.y])
  306.         # Drawing text
  307.         elif self.drawing_fun == self.canvas.create_text:
  308.             self.string = ''
  309.             self.drawing = self.drawing_fun(e.x, e.y ,text=self.string,
  310.                                             font = self.customFont,
  311.                                             fill=self.configFrame.get_text_colour())
  312.         # Moving object
  313.         elif self.drawing_fun == self.canvas.move:
  314.             self.startx = e.x
  315.             self.starty = e.y
  316.             self.moveID = self.canvas.find_closest(e.x, e.y)
  317.         # Deleting object
  318.         elif self.drawing_fun == self.canvas.delete:
  319.             ID = self.canvas.find_closest(e.x, e.y)
  320.             self.canvas.delete(ID)
  321.  
  322.     def releaseButton1(self, e):
  323.         """Left button is released"""
  324.         if self.drawing_fun in \
  325.                [self.canvas.create_rectangle,
  326.                 self.canvas.create_oval,
  327.                 self.canvas.move]:
  328.             self.drawing = None
  329.  
  330.  
  331.  
  332.     def keypress(self, e):
  333.         "Keyboard key is pressed"""
  334.         if self.drawing_fun == self.canvas.create_text:
  335.             if e.keysym == 'BackSpace':
  336.                 #if backspace is pressed remove last character typed
  337.                 self.string = self.string[:-1]
  338.             else:
  339.                 self.string += e.char
  340.             self.canvas.itemconfigure(self.drawing, text = self.string)
  341.            
  342.     def motion(self, e):
  343.         """Mouse motion without key press"""
  344.         if self.drawing_fun in \
  345.                [self.canvas.create_polygon, self.canvas.create_line]:
  346.             if len(self.points) == 2 and not self.drawing:
  347.                  self.drawing = \
  348.                     self.canvas.create_line(self.points+[e.x,e.y],
  349.                                             fill = 'white')
  350.             elif self.drawing:
  351.                 self.canvas.coords(*([self.drawing]+self.points+[e.x,e.y]))
  352.  
  353.     def b1Motion(self,e):
  354.         """Motion with left mouse pressed"""
  355.         if self.drawing_fun in \
  356.                [self.canvas.create_rectangle,self.canvas.create_oval]:
  357.             self.canvas.coords(self.drawing, self.startx, self.starty,
  358.                                e.x, e.y)
  359.         elif self.drawing_fun == self.canvas.move:
  360.             dx = e.x - self.startx
  361.             dy = e.y - self.starty
  362.             self.startx = e.x
  363.             self.starty = e.y
  364.             self.canvas.move(self.moveID, dx, dy)
  365.    
  366.     def press_button3(self, e):
  367.         """Middle mouse button pressed."""
  368.         if self.drawing_fun == self.canvas.create_polygon:
  369.             self.canvas.delete(self.drawing)
  370.             self.points.extend([e.x,e.y])
  371.             self.drawing_fun(self.points,
  372.                              outline = self.configFrame.get_line_colour(),
  373.                              fill = self.configFrame.get_fill_colour())
  374.             self.points = []
  375.             self.drawing = None
  376.         elif self.drawing_fun == self.canvas.create_line:
  377.             self.canvas.delete(self.drawing)
  378.             self.points.extend([e.x,e.y])
  379.             self.drawing_fun(self.points,
  380.                              fill = self.configFrame.get_line_colour(),
  381.                              width=self.configFrame.get_line_width())
  382.             self.points = []
  383.             self.drawing = None
  384.  
  385. root = Tk()
  386. app = DrawingApp(root)
  387. root.mainloop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement