.. _sec-drawing-on-a-canvas: ===================== Drawing on a canvas ===================== [status: content-mostly-written] .. rubric:: Prerequisites * The 10-hour "serious programming" course. * A GNU/Linux system with python3 and python3-tk installed (on an Ubuntu 16.04 system this can be done with ``sudo apt install python3-tk``) Simplest canvas =============== Drawing is usually done with the help of a graphical toolkit library. This library usually supports `widgets` and allows them to be arranged in a window on the scren. The widget for drawing is called a `canvas` and in :numref:`listing-canvas-trivial-py` is a simple example using Python's ``tkinter`` widget set. .. _listing-canvas-trivial-py: .. literalinclude:: canvas_trivial.py :language: python :caption: Program which draws two circles and a line. Things to notice about this program: * It uses the library ``tkinter`` which provides calls to create a window and draw things in it. * The calls ``root = Tk()`` and ``w.pack()`` and ``mainloop`` are boiler-plate: almost all programs that use the tkinter toolkit will use them. * ``w = Canvas(...)`` creates a canvas with the given width and height. ``w.pack()`` places that canvas into the window we are using. * After the drawing calls ``create_oval()`` and ``create_line()`` we call ``mainloop()``. This enters an `event loop` in which the widget set is waiting for events, such as the click of a button. We have not created any buttons, so ``mainloop()`` will just hang until we interrupt the progrma. Simplest animation ================== Animation can be done simply by drawing onto a canvas, then changing the drawing after a small amount of time and refreshing the canvas. In listing :numref:`listing-animation-trivial-py` .. _listing-animation-trivial-py: .. literalinclude:: animation_trivial.py :language: python :caption: Program which animates a circle whose radius is growing and shrinking. Note that this kind of animation is not ideal: it works well, but it does not allow the program to respond to any user input or other events. For us this is OK because we are purely showing the animation, and we are not setting up any buttons or other parts to the program, but the ``tkinter`` library offers a more appropriate approach to doing animations with a method called ``after()`` which allows you to call your drawing routines and handle user interface events at the same time. Exercises --------- .. exercise:: Modify the tirial animation program in :numref:`listing-animation-trivial-py` to write the current at the bottom of the canvas. A web search for "tkinter write string on canvas" might help. .. exercise:: Study how colors can be represented as combinations of *red*, *green* and *blue* (RGB) values. Read the introductory part of the Wikipedia article on the subject at https://en.wikipedia.org/wiki/RGB_color_model and then use the program `gpick` to examine how the various screen pixel colors can be represented as red, green and blue. Explore the program in detail, looking at how you can specify the RGB values and see what the result is, but you can also pick them from a color wheel, and you also use the `screen picker` FIXME... .. exercise:: Modify the trivial animation program in :numref:`listing-animation-trivial-py` to cycle through the colors as well as the radius. Aim for a psychadelic effect. Note that the ``fill=`` field in ``create_oval()`` can be a descriptive color name (like the ``"blue"`` that we used) but it can also specify the RGB (red, green, blue) values that form the color. A web search for "tkinter colors" might help.