Chapter 5 Graphics
We’ve been doing command line programming, but now it’s time to try GUI programming—programming in a graphical user interface, using a mouse. Python provides a graphics library called Tkinter But we’ll use the smaller graphics library provided by our textbook, graphics.py You should be able to access the graphics.py automatically. Test it by typing: >>>import graphics. If you don’t get an error message, all is well. If you do get an error message, copy the graphics.py file (available on our course web page) to the directory where you keep your Python files. Then test again, as above.
Object-oriented programming (OOP) involves programming using objects. An object represents an entity in the real world that can be distinctly identified. For example, a student, a desk, a circle, a button, and even a loan can all be viewed as objects. An object has a unique identity, state, and behaviors. The state of an object consists of a set of data fields (also known as properties) with their current values. The behavior of an object is defined by a set of methods.
An object has both a state and behavior. The state defines the object, and the behavior defines what the object does.
Once you create an object or import a library with objects, you can easily access the functions (or methods) and properties (or data) of an object using a dot separator. For example, we already have been accessing both properties and functions of the Math library: Math.pi will return the value of Pi, and Math.round(x) will take the value of x and round it up to the nearest integer.
Be sure the graphics.py file is in the same directory as your other Python files. For any program you’re writing that will use graphics, you’ll need to write import graphics in the very first line, even before you write def main(). However, this means you’d have to type graphics.Function() every time. A shorthand: from graphics import * Then you can just type the name of the function without the prefix graphics.
The first thing you have to do in a graphics program is create the window. The syntax to do this is: >>>win = GraphWin() This creates an object, called win, which is the window. You can use any identifier you want, as long as it follows Python naming rules. At the end of the program, you should probably destroy your window with >>>win.close()
A screen is comprised of pixels, or picture elements, tiny dots of light that can be any color. The higher the number of pixels, the clearer the picture. For example, the better HD flat-screen TVs are 1040p, vs. 720p for cheaper models. The default size of the GraphWin() window is 200 tall x 200 wide pixels, or 40,000 pixels in all. You can change the size of the window by using parameters: GraphWin(“My Window”,300, 200) will create a taller window than the default with My Window as the title. TRY THIS
The default size of the graphics window created by GraphWin() is 200 x 200 pixels But this can get cumbersome. You can simplify things by setting “artificial” coordinates. win = GraphWin(“Tic-tac-toe”) win.setCoords(0.0,0.0,3.0,3.0)
The graphics library comes with built-in functions which allow us to easily draw in Python. Point(x,y) creates a point at the coordinates provided by x and y. The x value refers to the x axis, the horizontal axis, while the y value refers to the y axis, the vertical axis. Once you’ve created a point object, you can retrieve the x and y values using the getX() and getY() functions. >>>nuPt = Point(22, 66) >>>nuPt.getX() 22 TRY THIS
The Line() function takes two points as its parameters. You can either pre-define the points or use the Point() function. >>>myL = Line(Point(22, 44), Point(44, 66)) Then you need to actually draw the line in the window you created: >>>myL.draw(win) Want to add arrows? The setArrow(string) function does this: >>>myL.setArrow(‘first’) TRY THIS
The Circle() function takes two parameters, a center point and a radius >>>nuCirc = Circle(Point(55,55), 90) And then draw it: >>>nuCirc.draw(win) getRadius() returns the radius: nuCirc.getRadius() TRY THIS
To create a rectangle, use the Rectangle(point1, point2) function, where p1 and p2 are the upper left and lower right corner points of the rectangle, respectively. >>>myR = Rectangle(Point(22, 66), Point(128, 200)) >>>myR.draw(win) TRY THIS
The best way to think of an oval is as a rectangle with an oval inside. Ergo, the Oval() function takes two points as parameters, the upper left and lower right point of a rectangle bounding the oval. To put an oval in the rectangle already created: >>>myOval = Oval(Point(22, 66), Point(128, 200)) >>>myOval.draw(win) TRY THIS
The move(dx, dy) function will move any graphical object x pixels to the right and y pixels up. If I wanted to move my circle to the right 80 pixels, I would type: >>>nuCirc.move(80,0) You can move objects ot the left and down by using negative numbers: >>>myOval.move(-20, -30) TRY THIS
You can change the color of any object using the setFill(string) function. If I wanted a green circle, I would type: >>>nuCirc.setFill(‘green’) Python recognizes standard colors, but if you want to know what a color is named, you can use RGB values. To do this (for example), type >>>color_rgb(100, 200, 300) and the string returns: #64c812c You can then use that string to set a color Sadly, my favorite color, teal, is not supported You can also change the color of the outline of a graphical object: >>>nuCirc.setOutline(‘blue’) Make your circle green with a blue outline
My dog, Rae, likes to chase red balls. Write a program that throws a ball across the screen. Hints: use a defined loop to move the ball. Remember that syntax? for x in range(500): The range number should be the width of your window. Then use the move() function to move your circle across the window This will happen really quickly, so you might want to use p = myWin.getMouse() to wait for a click from the user
When we create a graphical object >>>myOval = Oval(Point(22, 66), Point(128, 200)) we are creating an INSTANCE of the CLASS Oval Instances of classes INHERIT properties and methods from their parent classes. When we create an object, we are CONSTRUCTING it, and the method which creates it is called a CONSTRUCTOR, such as Oval(Point(22, 66), Point(128, 200)) The individual values of the instance (above, (Point(22, 66), Point(128, 200)) are stored as INSTANCE VARIABLES associated with the instance.
So any instance has unique values (or properties or states) associated with it. In the case of >>>nuPt = Point(22, 66) the unique values (or instance variables) are the point’s two coordinates. When we use nuPt.getX(), we are accessing those associated values; the getX() function is known as an accessor. When we move an object, we are changing those values. Ergo, nuPt.move(0, 25) is known as a mutator, since it mutates the values.
You can make your graphics respond to a user’s mouse clicks. The function getMouse() will return the coordinates of the point where the mouse was clicked. >>>pt1 = win.getMouse() will return the x and y coordinates.
# triangle.pyw # Interactive graphics program to draw a triangle from graphics import * def main(): win = GraphWin("Draw a Triangle") win.setCoords(0.0, 0.0, 10.0, 10.0) message = Text(Point(5, 0.5), "Click on three points") message.draw(win) # Get and draw three vertices of triangle p1 = win.getMouse() p1.draw(win) p2 = win.getMouse() p2.draw(win) p3 = win.getMouse() p3.draw(win) # Use Polygon object to draw the triangle triangle = Polygon(p1,p2,p3) triangle.setFill("peachpuff") triangle.setOutline("cyan") triangle.draw(win) # Wait for another click to exit message.setText("Click anywhere to quit.") win.getMouse() main()
Starting with the code on p. 143 of our text, create an interactive tic-tac-toe game. Users can click in any of 9 squares and alternate creating Xs or Os.
from graphics import * def main(): win = GraphWin("Tic-tac-toe") win.setCoords(0.0,0.0,3.0,3.0) Line(Point(1,0), Point(1,3)).draw(win) Line(Point(2,0), Point(2,3)).draw(win) Line(Point(0,1), Point(3,1)).draw(win) Line(Point(0,2), Point(3,2)).draw(win) main()
To create a message on a Python window, use the Text(anchorPoint, string) constructor: >>>prompt=Text(Point(50, 100), “Abandon hope all ye who enter here”) setText(str) will change the words associated with the text object: prompt.setText(“Hope is all”) setFace(font_family) will change the font: prompt.setFace(‘times roman’)
>>>prompt=Text(Point(50, 100), “Abandon hope all ye who enter here”) getText() returns the string associated with the text object: prompt.getText() To set the font size, use the setSize(point) function: prompt.setSize(36) puts the text into 36 point font. prompt.setStyle(‘italic’) will display the text in italics prompt.setTextColor(‘green’) will display the text in green—though probably not Titan green.
The Entry constructor creates a text box in which users can enter data inp = Entry(Point(50, 100), 5) setText(string) puts default text in the Entry box: inp.setText(“Enter data”) You still have to draw it: inp.draw(win) Sets the center point of the box Number of characters box will hold
Just like with the Text object, you can change the displayed text in the Entry box setText(string) setSize(point) setStyle(italic, bold, bold italic) setTextColor(color)
from graphics import * def main(): win = GraphWin("Celsius Converter", 300, 200) win.setCoords(0.0, 0.0, 3.0, 4.0) # Draw the interface Text(Point(1,3), " Celsius Temperature:").draw(win) Text(Point(1,1), "Fahrenheit Temperature:").draw(win) input = Entry(Point(2,3), 5) input.setText("0.0") input.draw(win) output = Text(Point(2,1),"") output.draw(win) button = Text(Point(1.5,2.0),"Convert It") button.draw(win) Rectangle(Point(1,1.5), Point(2,2.5)).draw(win) # wait for a mouse click win.getMouse() # convert input celsius = eval(input.getText()) fahrenheit = 9.0/5.0 * celsius + 32 # display output and change button output.setText("%0.1f" % fahrenheit) button.setText("Quit") # wait for click and then quit win.getMouse() win.close() main()
Images can be imported to a Python window using the Image(centerPoint, filename) function. JPEG and GIF picture file types are supported.