October 21, 2014
 
 
RSSRSS feed

Graphical Python Programming With PyGTK - page 2

Making a Push Button

  • May 14, 2009
  • By Akkana Peck

Whitespaces and formatting are meaningful in Python, so the code is posted both inline in this article, and on a separate page which is linked at the bottom.

To draw on a GTK drawing area, you need something called its drawable. Use widget.window to get that. Drawables let you get lots of useful properties, like the width and height of the area you're drawing in, widget.window.get_size.

Drawing in nearly all Linux toolkits requires something called a graphics context. That's an object which stores details about how you want to draw, like foreground and background colors, line width, line style and so forth. widget.window.new_gc() creates one. I've named mine xgc so it won't be confused with Python's garbage collector, which also uses the abbreviation gc.

Colors in PyGTK are a little tricky. You have to create a gtk.gdk.Color object and pass it to the graphics context's set_rgb_fg_color() function. You can use named colors with gtk.gdk.color_parse(), or you can define them by their red, green and blue values, like this for red: gtk.gdk.Color(65535, 0, 0).

Then you're ready to draw. PyGTK has lots of drawing functions to draw points, lines, rectangles, arcs, polygons and so on, but in the example above, I just draw a red line from the upper left corner (0, 0) to the lower right (w, h), to get Figure 3.

 

That's progress ... but it's boring. How about adding some circles and ovals? PyGTK uses a rather complicated function for that, so let's break it down:

drawable.draw_arc(gc, filled, x, y, width, height, angle1, angle2)
where gc is the graphics context, filled is whether you want an outline (False) or a filled-in shape (True). x and y are the coordinates of an imaginary box containing your oval, while width and height are the size of that box. Finally angle1 and angle2 are how much of the circle you want to draw, starting at the 3-o-clock position and proceeding counter-clockwise around the circle. Here's the tricky part: the units for angle1 and angle2 are 1/64ths of a degree. So if you want a full circle, use 0 for angle1 and 360*64 for angle2. If you want an arc that goes from the 45� point to 180�, you'd use angle1 = 45*64 and angle2 = 180*64 (Figure 4).

 

I know it sounds a bit complicated, so here's a sample of how it works in practice:

    xgc.set_rgb_fg_color(gtk.gdk.color_parse("yellow"))
widget.window.draw_arc(xgc, True, 200, 100, 200, 200, 0, 360*64)

xgc.set_rgb_fg_color(gtk.gdk.Color(0, 0, 0)) # black
widget.window.draw_arc(xgc, True, 240, 145, 30, 40, 0, 360*64)
widget.window.draw_arc(xgc, True, 330, 145, 30, 40, 0, 360*64)

xgc.line_width = 6
widget.window.draw_arc(xgc, False, 240, 150, 120, 110, 200*64, 140*64)

Try it and see what it does! (Figure 5.)

 

In the next article I'll show how to put this all together to make applications that look pretty, or useful, or both. But for now, you can find out more about PyGTK at the PyGTK website, where they have a very good reference manual as well as tutorials and other information. In particular, the reference page on drawables will tell you about all the different drawing methods you can use.

Here's the final program:

#!/usr/bin/env python

import gtk, random

# This function will be called whenever you click on the button:
def click_handler(widget) :
# quit the application:
gtk.main_quit()

# This function will be called whenever the drawing area is exposed:
def expose_handler(widget, event) :
w, h = widget.window.get_size()
xgc = widget.window.new_gc()

xgc.set_rgb_fg_color(gtk.gdk.color_parse("yellow"))
widget.window.draw_arc(xgc, True, 200, 100, 200, 200, 0, 360*64)
xgc.set_rgb_fg_color(gtk.gdk.Color(0, 0, 0)) # black
widget.window.draw_arc(xgc, True, 240, 145, 30, 40, 0, 360*64)
widget.window.draw_arc(xgc, True, 330, 145, 30, 40, 0, 360*64)
xgc.line_width = 6
widget.window.draw_arc(xgc, False, 240, 150, 120, 110, 200*64, 140*64)

# Create the main window:
win = gtk.Window()

# Organize widgets in a vertical box:
vbox = gtk.VBox()
win.add(vbox)

# Create an area to draw in:
drawing_area = gtk.DrawingArea()
drawing_area.set_size_request(600, 400)
vbox.pack_start(drawing_area)

drawing_area.connect("expose-event", expose_handler)

drawing_area.show()

# Make a pushbutton:
button = gtk.Button("Quit")

# When it's clicked, call our handler:
button.connect("clicked", click_handler)

# Add it to the window:
vbox.pack_start(button)
button.show()
# Obey the window manager quit signal:
win.connect("destroy", gtk.main_quit)

vbox.show()
win.show()

gtk.main()

Click here to see the whole program

Sitemap | Contact Us