Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # This code requires Python 3 and tkinter (which is usually installed by default)
- # This code will NOT work on trinket.io as the tkinter module is not supported
- # Raspberry Pi Foundation 2017
- # CC-BY-SA 4.0
- try:
- from tkinter import Tk, Canvas, BOTH
- except ImportError:
- print("tkinter did not import successfully - check you are running Python 3 and that tkinter is available.")
- exit(1)
- # create the tkinter object which will used in the Paper class.
- try:
- tk = Tk()
- except ValueError:
- print("Error: could not instantiate Paper object")
- exit(1)
- import random
- class Paper():
- def __init__(self, width=600, height=600):
- """Create a Paper object which allows shapes to be drawn onto it.
- """
- # Call the constructor from the superclass (tkinter's Tk)
- # Set some attributes
- tk.title( "Drawing shapes" )
- tk.geometry(str(width)+"x"+str(height))
- tk.paper_width = width
- tk.paper_height = height
- # Create a tkinter canvas object to draw on
- tk.canvas = Canvas(tk)
- tk.canvas.pack(fill=BOTH, expand=1)
- # return the instance of tk
- def __get__(self, instance, owner):
- return tk
- # allows Paper.display() to be called triggering the tk mainloop
- @staticmethod
- def display():
- """
- Displays the paper object
- """
- tk.mainloop()
- class Shape():
- # Static class variable removing the need to pass in a Paper object
- # to draw the shapes on
- paper = Paper()
- # Constructor for Shape
- def __init__(self, width=50, height=50, x=None, y=None, color="black"):
- """Creates a generic 'shape' which contains properties common to all
- shapes such as height, width, x y coordinates and colour.
- """
- # Set some attributes
- self.height = height
- self.width = width
- self.color = color
- # Put the shape in the centre if no xy coords were given
- if x is None:
- self.x = (self.paper.paper_width/2) - (self.width/2)
- else:
- self.x = x
- if y is None:
- self.y = (self.paper.paper_height/2) - (self.height/2)
- else:
- self.y = y
- # This is an internal method not meant to be called by users
- # (It has a _ before the method name to show this)
- def _location(self):
- """Internal method used by the class to get the location
- of the shape. This shouldn't be called by users, hence why its
- name begins with an underscore.
- """
- x1 = self.x
- y1 = self.y
- x2 = self.x + self.width
- y2 = self.y + self.height
- return [x1, y1, x2, y2]
- # Randomly generate what the shape looks like
- def randomize(self, smallest=20, largest=200):
- """Randomly generates width, height, position and colour for a shape. You can specify
- the smallest and largest random size that will be generated. If not specified, the
- generated shape will default to a random size between 20 and 200.
- """
- self.width = random.randint(smallest, largest)
- self.height = random.randint(smallest, largest)
- self.x = random.randint(0, self.paper.paper_width-self.width)
- self.y = random.randint(0, self.paper.paper_height-self.height)
- self.color = random.choice(["red", "yellow", "blue", "green", "gray", "white", "black", "cyan", "pink", "purple"])
- # Getters and setters for Shape attributes
- def set_width(self, width):
- """Sets the width of the shape"""
- self.width = width
- def set_height(self,height):
- """Sets the height of the shape"""
- self.height = height
- def set_x(self, x):
- """Sets the x position of the shape"""
- self.x = x
- def set_y(self, y):
- """Sets the y position of the shape"""
- self.y = y
- def set_color(self, color):
- """Sets the colour of the shape"""
- self.color = color
- def get_color(self):
- """Returns the colour of the shape"""
- return self.color
- # Rectangle class is a subclass of Shape
- class Rectangle(Shape):
- # This is how to draw a rectangle
- def draw(self):
- """Draws a rectangle on the canvas. The properties of the rectangle
- can be set using the getter and setter methods in Shape"""
- x1, y1, x2, y2 = self._location()
- # Draw the rectangle
- self.paper.canvas.create_rectangle(x1, y1, x2, y2, fill=self.color)
- class Oval(Shape):
- def draw(self):
- """Draws an oval on the canvas. The properties of the oval
- can be set using the getter and setter methods in Shape"""
- x1, y1, x2, y2 = self._location()
- # Draw the oval
- self.paper.canvas.create_oval(x1, y1, x2, y2, fill=self.color)
- class Triangle(Shape):
- # Every constructor parameter has a default setting
- # e.g. color defaults to "black" but you can override this
- def __init__(self, x1=0, y1=0, x2=20, y2=0, x3=20, y3=20, color="black"):
- """Overrides the Shape constructor because triangles require three
- coordinate points to be drawn, unlike rectangles and ovals."""
- try:
- super().__init__(color=color)
- except ValueError:
- print("Error: could not instantiate Triangle")
- # Remove height and width attributes which make no sense for a triangle
- # (triangles are drawn via 3 xy coordinates)
- del self.height
- del self.width
- # Instead add three coordinate attributes
- self.x = x1
- self.y = y1
- self.x2 = x2
- self.y2 = y2
- self.x3 = x3
- self.y3 = y3
- def _location(self):
- """Internal method used by the class to get the location
- of the triangle. This shouldn't be called by users, hence why its
- name begins with an underscore.
- """
- return [self.x, self.y, self.x2, self.y2, self.x3, self.y3]
- def draw(self):
- """Draws a triangle on the canvas. The properties of the triangle
- can be set using the getter and setter methods in Shape"""
- x1, y1, x2, y2, x3, y3 = self._location()
- # Draw a triangle
- self.paper.canvas.create_polygon(x1, y1, x2, y2, x3, y3, fill=self.color)
- def randomize(self):
- """Randomly chooses the location of all 3 triangle points as well
- as the colour of the triangle"""
- # Randomly choose all the points of the triangle
- self.x = random.randint(0, self.paper.paper_width)
- self.y = random.randint(0, self.paper.paper_height)
- self.x2 = random.randint(0, self.paper.paper_width)
- self.y2 = random.randint(0, self.paper.paper_height)
- self.x3 = random.randint(0, self.paper.paper_width)
- self.y3 = random.randint(0, self.paper.paper_height)
- # Randomly choose a colour of this triangle
- self.color = random.choice(["red", "yellow", "blue", "green", "gray", "white", "black", "cyan", "pink", "purple"])
- # Change the behaviour of set_width and set_height methods for a triangle
- # because triangles are not drawn in the same way
- def set_width(self, width):
- """Overrides the setter method for width"""
- print("Width is not defined for Triangle objects")
- def set_height(self, height):
- """Overrides the setter method for height"""
- print("Height is not defined for Triangle objects")
- # This if statement means
- # "if you run this file (rather than importing it), run this demo script"
- if __name__ == "__main__":
- # Random size and location triangle
- tri = Triangle()
- tri.randomize()
- tri.draw()
- # Specific size and location rectangle
- rect = Rectangle(height=40, width=90, x=110, y=20, color="yellow")
- rect.draw()
- # Default oval
- oval = Oval()
- oval.draw()
- # Oval with setters
- oval2 = Oval()
- oval2.set_height(200)
- oval2.set_width(100)
- oval2.set_color("fuchsia")
- oval2.set_x(30)
- oval2.set_y(90)
- oval2.draw()
- Paper.display()
Add Comment
Please, Sign In to add comment