Showing posts with label Tkinter. Show all posts
Showing posts with label Tkinter. Show all posts

Nibbles in Tkinter Programming

Nibbles

In this part of the Tkinter tutorial, we will create a Nibbles game clone.
Nibbles is an older classic video game. It was first created in late 70s. Later it was brought to PCs. In this game the player controls a snake. The objective is to eat as many apples as possible. Each time the snake eats an apple, its body grows. The snake must avoid the walls and its own body.

Development

The size of each of the joints of a snake is 10px. The snake is controlled with the cursor keys. Initially, the snake has three joints. The game starts immediately. When the game is finished, we display "Game Over" message in the center of the window.
We use the Canvas widget to create the game. The objects in the game are images. We use canvas methods to create image items. We use canvas methods to find items on the canvas using tags and to do collision detection.
#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
ZetCode Tkinter tutorial

This is a simple Nibbles game
clone.

author: Jan Bodnar
website: zetcode.com
last edited: January 2011
"""


import sys
import random
from PIL import Image, ImageTk
from Tkinter import Tk, Frame, Canvas, ALL, NW


WIDTH = 300
HEIGHT = 300
DELAY = 100
DOT_SIZE = 10
ALL_DOTS = WIDTH * HEIGHT / (DOT_SIZE * DOT_SIZE)
RAND_POS = 27

x = [0] * ALL_DOTS
y = [0] * ALL_DOTS


class Board(Canvas):

def __init__(self, parent):
Canvas.__init__(self, width=WIDTH, height=HEIGHT,
background="black", highlightthickness=0)

self.parent = parent
self.initGame()
self.pack()


def initGame(self):

self.left = False
self.right = True
self.up = False
self.down = False
self.inGame = True
self.dots = 3

self.apple_x = 100
self.apple_y = 190

for i in range(self.dots):
x[i] = 50 - i * 10
y[i] = 50

try:
self.idot = Image.open("dot.png")
self.dot = ImageTk.PhotoImage(self.idot)
self.ihead = Image.open("head.png")
self.head = ImageTk.PhotoImage(self.ihead)
self.iapple = Image.open("apple.png")
self.apple = ImageTk.PhotoImage(self.iapple)

except IOError, e:
print e
sys.exit(1)

self.focus_get()

self.createObjects()
self.locateApple()
self.bind_all("<Key>", self.onKeyPressed)
self.after(DELAY, self.onTimer)


def createObjects(self):

self.create_image(self.apple_x, self.apple_y, image=self.apple,
anchor=NW, tag="apple")
self.create_image(50, 50, image=self.head, anchor=NW, tag="head")
self.create_image(30, 50, image=self.dot, anchor=NW, tag="dot")
self.create_image(40, 50, image=self.dot, anchor=NW, tag="dot")


def checkApple(self):

apple = self.find_withtag("apple")
head = self.find_withtag("head")

x1, y1, x2, y2 = self.bbox(head)
overlap = self.find_overlapping(x1, y1, x2, y2)

for ovr in overlap:

if apple[0] == ovr:

x, y = self.coords(apple)
self.create_image(x, y, image=self.dot, anchor=NW, tag="dot")
self.locateApple()


def doMove(self):

dots = self.find_withtag("dot")
head = self.find_withtag("head")

items = dots + head

z = 0
while z < len(items)-1:
c1 = self.coords(items[z])
c2 = self.coords(items[z+1])
self.move(items[z], c2[0]-c1[0], c2[1]-c1[1])
z += 1

if self.left:
self.move(head, -DOT_SIZE, 0)

if self.right:
self.move(head, DOT_SIZE, 0)

if self.up:
self.move(head, 0, -DOT_SIZE)

if self.down:
self.move(head, 0, DOT_SIZE)


def checkCollisions(self):

dots = self.find_withtag("dot")
head = self.find_withtag("head")

x1, y1, x2, y2 = self.bbox(head)
overlap = self.find_overlapping(x1, y1, x2, y2)

for dot in dots:
for over in overlap:
if over == dot:
self.inGame = False

if x1 < 0:
self.inGame = False

if x1 > WIDTH - DOT_SIZE:
self.inGame = False

if y1 < 0:
self.inGame = False

if y1 > HEIGHT - DOT_SIZE:
self.inGame = False


def locateApple(self):

apple = self.find_withtag("apple")
self.delete(apple[0])

r = random.randint(0, RAND_POS)
self.apple_x = r * DOT_SIZE
r = random.randint(0, RAND_POS)
self.apple_y = r * DOT_SIZE

self.create_image(self.apple_x, self.apple_y, anchor=NW,
image=self.apple, tag="apple")


def onKeyPressed(self, e):

key = e.keysym

if key == "Left" and not self.right:
self.left = True
self.up = False
self.down = False


if key == "Right" and not self.left:
self.right = True
self.up = False
self.down = False


if key == "Up" and not self.down:
self.up = True
self.right = False
self.left = False


if key == "Down" and not self.up:
self.down = True
self.right = False
self.left = False


def onTimer(self):

if self.inGame:
self.checkCollisions()
self.checkApple()
self.doMove()
self.after(DELAY, self.onTimer)
else:
self.gameOver()


def gameOver(self):

self.delete(ALL)
self.create_text(self.winfo_width()/2, self.winfo_height()/2,
text="Game Over", fill="white")


class Nibbles(Frame):

def __init__(self, parent):
Frame.__init__(self, parent)

parent.title('Nibbles')
self.board = Board(parent)
self.pack()


def main():

root = Tk()
nib = Nibbles(root)
root.mainloop()


if __name__ == '__main__':
main()
First we will define some constants used in our game.
The WIDTH and HEIGHT constants determine the size of the Board. The DELAY constant determines the speed of the game. The DOT_SIZE is the size of the apple and the dot of the snake. The ALL_DOTS constant defines the maximum number of possible dots on the Board. The RAND_POS constant is used to calculate a random position of an apple.
x = [0] * ALL_DOTS
y = [0] * ALL_DOTS
These two arrays store x, y coordinates of all possible joints of a snake.
The initGame() method initializes variables, loads images and starts a timeout function.
try:
self.idot = Image.open("dot.png")
self.dot = ImageTk.PhotoImage(self.idot)
self.ihead = Image.open("head.png")
self.head = ImageTk.PhotoImage(self.ihead)
self.iapple = Image.open("apple.png")
self.apple = ImageTk.PhotoImage(self.iapple)

except IOError, e:
print e
sys.exit(1)
In these lines, we load our images. There are three images in the Nibbles game. The head, the dot and the apple.
self.createObjects()
self.locateApple()
The createObjects() method creates items on the canvas. The locateApple() puts an apple randomly on the canvas.
self.bind_all("<Key>", self.onKeyPressed)
We bind the keyboard events to the onKeyPressed() method. The game is controlled with keyboard cursor keys.
def createObjects(self):

self.create_image(self.apple_x, self.apple_y, image=self.apple,
anchor=NW, tag="apple")
self.create_image(50, 50, image=self.head, anchor=NW, tag="head")
self.create_image(30, 50, image=self.dot, anchor=NW, tag="dot")
self.create_image(40, 50, image=self.dot, anchor=NW, tag="dot")
In the createObjects() method, we create game objects on the canvas. These are canvas items. They are given initial x, y coordinates. The image parameter provides the image to be displayed. The anchorparameter is set to NW; this way the coordinates of the canvas item are the top-left points of the items. This is important if we want to be able to display images next to the borders of the root window. If you don't know what I mean, try to delete the anchor parameter. The tag parameter is used to identify items on the canvas. One tag may be used for multiple canvas items.
The checkApple() method checks, if the snake has hit the apple object. If so, we add another snake joint and call the locateApple().
apple = self.find_withtag("apple")
head = self.find_withtag("head")
The find_withtag() method finds an item on the canvas using its tag. We need two items. The head of the snake and the apple. Note that even if there is only one item with a given tag, the method returns a tuple. This is a case for the apple item. And later the apple item is accessed the following way: apple[0].
x1, y1, x2, y2 = self.bbox(head)
overlap = self.find_overlapping(x1, y1, x2, y2)
The bbox() method returns the bounding box points of an item. The find_overlapping() method finds colliding items for the given coordinates.
for ovr in overlap:

if apple[0] == ovr:
x, y = self.coords(apple)
self.create_image(x, y, image=self.dot, anchor=NW, tag="dot")
self.locateApple()
If the apple collides with the head, we create a new dot item at the coordinates of the apple object. We call the locateApple() method, which deletes the old apple item from the canvas and creates and randomly positions a new one.
In the doMove() method we have the key algorithm of the game. To understand it, look at how the snake is moving. You control the head of the snake. You can change its direction with the cursor keys. The rest of the joints move one position up the chain. The second joint moves where the first was, the third joint where the second was etc.
z = 0
while z < len(items)-1:
c1 = self.coords(items[z])
c2 = self.coords(items[z+1])
self.move(items[z], c2[0]-c1[0], c2[1]-c1[1])
z += 1
This code moves the joints up the chain.
if self.left:
self.move(head, -DOT_SIZE, 0)
Move the head to the left.
In the checkCollisions() method, we determine if the snake has hit itself or one of the walls.
x1, y1, x2, y2 = self.bbox(head)
overlap = self.find_overlapping(x1, y1, x2, y2)

for dot in dots:
for over in overlap:
if over == dot:
self.inGame = False
Finish the game, if the snake hits one of its joints with the head.
if y1 > HEIGHT - DOT_SIZE:
self.inGame = False
Finish the game, if the snake hits the bottom of the Board.
The locateApple() method locates a new apple randomly on the board and deletes the old one.
apple = self.find_withtag("apple")
self.delete(apple[0])
Here we find and delete the apple, that was eaten by the snake.
r = random.randint(0, RAND_POS)
We get a random number from 0 to RAND_POS - 1.
self.apple_x = r * DOT_SIZE
...
self.apple_y = r * DOT_SIZE
These lines set the x, y coordinates of the apple object.
In the onKeyPressed() method of the Board class, we determine the keys that were pressed.
if key == "Left" and not self.right: 
self.left = True
self.up = False
self.down = False
If we hit the left cursor key, we set left variable to true. This variable is used in the doMove() method to change coordinates of the snake object. Notice also, that when the snake is heading to the right, we cannot turn immediately to the left.
def onTimer(self):

if self.inGame:
self.checkCollisions()
self.checkApple()
self.doMove()
self.after(DELAY, self.onTimer)
else:
self.gameOver()
Every DELAYms, the onTimer() method is called. If we are in the game, we call three methods, that build the logic of the game. Otherwise the game is finished. The timer is based on the after() method, which calls a method after DELAYms only once. To repeteadly call the timer, we recursively call the onTimer() method.
def gameOver(self):

self.delete(ALL)
self.create_text(self.winfo_width()/2, self.winfo_height()/2,
text="Game Over", fill="white")
If the game is over, we delete all items on the canvas. Then we draw "Game Over" in the center of the screen.
Nibbles
Figure: Nibbles
This was the Nibbles computer game created with the Tkinter library.
Continue Reading

Drawing in Tkinter Programming

Drawing

In this part of the Tkinter tutorial we will do some drawing. Drawing in Tkinter is done on the Canvas widget. Canvas is a high level facility for graphics in Tkinter.
It can be used to create charts, custom widgets or create games.

Colors

A color is an object representing a combination of Red, Green, and Blue (RGB) intensity values.
#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
ZetCode Tkinter tutorial

This program draws three
rectangles filled with different
colors.

author: Jan Bodar
last modified: January 2011
website: www.zetcode.com
"""

from Tkinter import Tk, Canvas, Frame, BOTH


class Example(Frame):

def __init__(self, parent):
Frame.__init__(self, parent)

self.parent = parent
self.initUI()

def initUI(self):

self.parent.title("Colors")
self.pack(fill=BOTH, expand=1)

canvas = Canvas(self)
canvas.create_rectangle(30, 10, 120, 80,
outline="#fb0", fill="#fb0")
canvas.create_rectangle(150, 10, 240, 80,
outline="#f50", fill="#f50")
canvas.create_rectangle(270, 10, 370, 80,
outline="#05f", fill="#05f")
canvas.pack(fill=BOTH, expand=1)


def main():

root = Tk()
ex = Example(root)
root.geometry("400x100+300+300")
root.mainloop()


if __name__ == '__main__':
main()
In the code example, we draw three rectangles and fill them with different color values.
canvas = Canvas(self)
We create the Canvas widget.
canvas.create_rectangle(30, 10, 120, 80, 
outline="#fb0", fill="#fb0")
The create_rectangle() creates a rectangle item on the canvas. The first four parameters are the x,y coordinates of the two bounding points. The top-left and the bottom-right. With the outline parameter we control the color of the outline of the rectangle. Likewise, the fillparameter provides a color for the inside of the rectangle.
Colors
Figure: Colors

Shapes

We can draw various shapes on the Canvas. The following code example will show some of them.
#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
ZetCode Tkinter tutorial

In this script, we draw basic
shapes on the canvas.

author: Jan Bodar
last modified: January 2011
website: www.zetcode.com
"""

from Tkinter import Tk, Canvas, Frame, BOTH


class Example(Frame):

def __init__(self, parent):
Frame.__init__(self, parent)

self.parent = parent
self.initUI()

def initUI(self):

self.parent.title("Shapes")
self.pack(fill=BOTH, expand=1)

canvas = Canvas(self)
canvas.create_oval(10, 10, 80, 80, outline="red",
fill="green", width=2)
canvas.create_oval(110, 10, 210, 80, outline="#f11",
fill="#1f1", width=2)
canvas.create_rectangle(230, 10, 290, 60,
outline="#f11", fill="#1f1", width=2)
canvas.create_arc(30, 200, 90, 100, start=0,
extent=210, outline="#f11", fill="#1f1", width=2)

points = [150, 100, 200, 120, 240, 180, 210,
200, 150, 150, 100, 200]
canvas.create_polygon(points, outline='red',
fill='green', width=2)

canvas.pack(fill=BOTH, expand=1)


def main():

root = Tk()
ex = Example(root)
root.geometry("330x220+300+300")
root.mainloop()


if __name__ == '__main__':
main()
We draw five different shapes on the window. A circle, an ellipse, a rectangle, an arc and a polygon. Outlines are drawn in red, insides in green. The width of the outline is 2px.
canvas.create_oval(10, 10, 80, 80, outline="red", 
fill="green", width=2)
Here the create_oval() method is used to create a circle item. The first four parameters are the bounding box coordinates of the circle. In other words, they are x, y coordinates of the top-left and bottom-right points of the box, in which the circle is drawn.
canvas.create_rectangle(230, 10, 290, 60, 
outline="#f11", fill="#1f1", width=2)
We create a rectangle item. The coordinates are again the bounding box of the rectangle to be drawn.
canvas.create_arc(30, 200, 90, 100, start=0, 
extent=210, outline="#f11", fill="#1f1", width=2)
This code line creates an arc. An arc is a part of the circumference of the circle. We provide the bounding box. The start parameter is the start angle of the arc. The extent is the angle size.
points = [150, 100, 200, 120, 240, 180, 210, 
200, 150, 150, 100, 200]
canvas.create_polygon(points, outline='red',
fill='green', width=2)
A polygon is created. It is a shape with multiple corners. To create a polygon in Tkinter, we provide the list of polygon coordinates to the create_polygon() method.
Shapes
Figure: Shapes

Drawing image

In the following example we will create an image item on the canvas.
#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
ZetCode Tkinter tutorial

In this script, we draw an image
on the canvas.

author: Jan Bodar
last modified: December 2010
website: www.zetcode.com
"""

from Tkinter import Tk, Canvas, Frame, BOTH, NW
import Image
import ImageTk

class Example(Frame):

def __init__(self, parent):
Frame.__init__(self, parent)

self.parent = parent
self.initUI()

def initUI(self):

self.parent.title("High Tatras")
self.pack(fill=BOTH, expand=1)

self.img = Image.open("tatras.jpg")
self.tatras = ImageTk.PhotoImage(self.img)

canvas = Canvas(self, width=self.img.size[0]+20,
height=self.img.size[1]+20)
canvas.create_image(10, 10, anchor=NW, image=self.tatras)
canvas.pack(fill=BOTH, expand=1)


def main():

root = Tk()
ex = Example(root)
root.mainloop()


if __name__ == '__main__':
main()
We display an image on the canvas.
self.img = Image.open("tatras.jpg")
self.tatras = ImageTk.PhotoImage(self.img)
Tkinter does not support jpg images internally. As a workaround, we use the Image and ImageTk modules.
canvas = Canvas(self, width=self.img.size[0]+20, 
height=self.img.size[1]+20)
We create the Canvas widget. It takes the size of the image into account. It is 20px wider and 20px higher than the actual image size.
canvas.create_image(10, 10, anchor=NW, image=self.tatras)
We use the create_image() method to create an image item on the canvas. To show the whole image, it is anchored to the north and to the west. The image parameter provides the photo image to display.

Drawing text

In the last example, we are going to draw text on the window.
#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
ZetCode Tkinter tutorial

In this script, we draw text
on the window.

author: Jan Bodar
last modified: December 2010
website: www.zetcode.com
"""

from Tkinter import Tk, Canvas, Frame, BOTH, W


class Example(Frame):

def __init__(self, parent):
Frame.__init__(self, parent)

self.parent = parent
self.initUI()

def initUI(self):

self.parent.title("Lyrics")
self.pack(fill=BOTH, expand=1)

canvas = Canvas(self)
canvas.create_text(20, 30, anchor=W, font="Purisa",
text="Most relationships seem so transitory")
canvas.create_text(20, 60, anchor=W, font="Purisa",
text="They're good but not the permanent one")
canvas.create_text(20, 130, anchor=W, font="Purisa",
text="Who doesn't long for someone to hold")
canvas.create_text(20, 160, anchor=W, font="Purisa",
text="Who knows how to love without being told")
canvas.create_text(20, 190, anchor=W, font="Purisa",
text="Somebody tell me why I'm on my own")
canvas.create_text(20, 220, anchor=W, font="Purisa",
text="If there's a soulmate for everyone")
canvas.pack(fill=BOTH, expand=1)


def main():

root = Tk()
ex = Example(root)
root.geometry("420x250+300+300")
root.mainloop()


if __name__ == '__main__':
main()
We draw a lyrics of a song on the window.
canvas.create_text(20, 30, anchor=W, font="Purisa",
text="Most relationships seem so transitory")
The first two parameters are the x, y coordinates of the center point of the text. If we anchor the text item to the west, the text starts from this position. The fontparameter provides the font of the text and the textparameter is the text to be displayed.
Drawing text
Figure: Drawing text
In this part of the Tkinter tutorial, we did some drawing.
Continue Reading

Dialogs in Tkinter

Dialogs in Tkinter

In this part of the Tkinter tutorial, we will work with dialogs.
Dialog windows or dialogs are an indispensable part of most modern GUI applications. A dialog is defined as a conversation between two or more persons. In a computer application a dialog is a window which is used to "talk" to the application. A dialog is used to input data, modify data, change the application settings etc. Dialogs are important means of communication between a user and a computer program.

Message boxes

Message boxes are convenient dialogs that provide messages to the user of the application. The message consists of text and image data. Message boxes in Tkinter are located in the tkMessageBox module.
#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
ZetCode Tkinter tutorial

In this program, we show various
message boxes.

author: Jan Bodnar
last modified: January 2011
website: www.zetcode.com
"""

from ttk import Frame, Button, Style
from Tkinter import Tk, BOTH
import tkMessageBox as box


class Example(Frame):

def __init__(self, parent):
Frame.__init__(self, parent)

self.parent = parent
self.initUI()

def initUI(self):

self.parent.title("Message boxes")
self.style = Style()
self.style.theme_use("default")
self.pack()

error = Button(self, text="Error", command=self.onError)
error.grid()
warning = Button(self, text="Warning", command=self.onWarn)
warning.grid(row=1, column=0)
question = Button(self, text="Question", command=self.onQuest)
question.grid(row=0, column=1)
inform = Button(self, text="Information", command=self.onInfo)
inform.grid(row=1, column=1)


def onError(self):
box.showerror("Error", "Could not open file")

def onWarn(self):
box.showwarning("Warning", "Deprecated function call")

def onQuest(self):
box.askquestion("Question", "Are you sure to quit?")

def onInfo(self):
box.showinfo("Information", "Download completed")


def main():

root = Tk()
ex = Example(root)
root.geometry("300x150+300+300")
root.mainloop()


if __name__ == '__main__':
main()
We use the grid manager to set up a grid of four buttons. Each of the buttons shows a different message box.
import tkMessageBox as box
We import the tkMessageBox which has the functions, that show dialogs.
error = Button(self, text="Error", command=self.onError)
We create an error button, which calls the onError() method. Inside the method, we show the error message dialog.
def onError(self):
box.showerror("Error", "Could not open file")
In case we pressed the error button, we show the error dialog. We use the showerror() function to show the dialog on the screen. The first parameter of this method is the title of the message box, the second parameter is the actual message.
Warning message dialog
Figure: Warning message dialog

Color chooser

The color chooser is a dialog for selecting a color. It is located in the tkColorChooser module.
#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
ZetCode Tkinter tutorial

In this script, we use tkColorChooser
dialog to change the background of a frame.

author: Jan Bodnar
last modified: January 2011
website: www.zetcode.com
"""

from Tkinter import Tk, Frame, Button, BOTH, SUNKEN
import tkColorChooser

class Example(Frame):

def __init__(self, parent):
Frame.__init__(self, parent)

self.parent = parent
self.initUI()

def initUI(self):

self.parent.title("Color chooser")
self.pack(fill=BOTH, expand=1)

self.btn = Button(self, text="Choose Color",
command=self.onChoose)
self.btn.place(x=30, y=30)

self.frame = Frame(self, border=1,
relief=SUNKEN, width=100, height=100)
self.frame.place(x=160, y=30)

def onChoose(self):

(rgb, hx) = tkColorChooser.askcolor()
self.frame.config(bg=hx)


def main():

root = Tk()
ex = Example(root)
root.geometry("300x150+300+300")
root.mainloop()


if __name__ == '__main__':
main()
We have a button and a frame. Clicking on the button we show a color chooser dialog. We will change the background color of the frame by selecting a color from the dialog.
(rgb, hx) = tkColorChooser.askcolor()
self.frame.config(bg=hx)
The askcolor() function shows the dialog. If we click OK, a tuple is returned. It is a color value in RGB and hexadecimal format. In the second line we change the background color of the frame, given the color value.
Color chooser
Figure: Color chooser

File dialog

tkFileDialog dialog allows a user to select a file from the filesystem.
#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
ZetCode Tkinter tutorial

In this program, we use the
tkFileDialog to select a file from
a filesystem.

author: Jan Bodar
last modified: January 2011
website: www.zetcode.com
"""


from Tkinter import Frame, Tk, BOTH, Text, Menu, END
import tkFileDialog

class Example(Frame):

def __init__(self, parent):
Frame.__init__(self, parent)

self.parent = parent
self.initUI()

def initUI(self):

self.parent.title("File dialog")
self.pack(fill=BOTH, expand=1)

menubar = Menu(self.parent)
self.parent.config(menu=menubar)

fileMenu = Menu(menubar)
fileMenu.add_command(label="Open", command=self.onOpen)
menubar.add_cascade(label="File", menu=fileMenu)

self.txt = Text(self)
self.txt.pack(fill=BOTH, expand=1)


def onOpen(self):

ftypes = [('Python files', '*.py'), ('All files', '*')]
dlg = tkFileDialog.Open(self, filetypes = ftypes)
fl = dlg.show()

if fl != '':
text = self.readFile(fl)
self.txt.insert(END, text)

def readFile(self, filename):

f = open(filename, "r")
text = f.read()
return text


def main():

root = Tk()
ex = Example(root)
root.geometry("300x250+300+300")
root.mainloop()


if __name__ == '__main__':
main()
In our code example, we use the tkFileDialog dialog to select a file and display its contents in a Text widget.
self.txt = Text(self)
This is the Text widget in which we will show the contents of a selected file.
ftypes = [('Python files', '*.py'), ('All files', '*')]
These are file filters. The first shows only Python files, the other shows all files.
dlg = tkFileDialog.Open(self, filetypes = ftypes)
fl = dlg.show()
The dialog is created and shown on the screen. We get the return value, which is the name of the selected file.
text = self.readFile(fl)
We read the contents of the file.
self.txt.insert(END, text)
The text is inserted into the Text widget.
tkFileDialog
Figure: tkFileDialog
In this part of the Tkinter tutorial, we worked with dialog windows.
Continue Reading

Menus And toolbars in Tkinter Programming

Menus And toolbars

In this part of the Tkinter tutorial, we will work with menus and toolbar.
A menubar is one of the most visible parts of the GUI application. It is a group of commands located in various menus. While in console applications you had to remember all those arcane commands, here we have most of the commands grouped into logical parts. There are accepted standards that further reduce the amount of time spending to learn a new application. Menus group commands that we can use in an application. Toolbars provide a quick access to the most frequently used commands.

Simple menu

The first example will show a simple menu.
#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
ZetCode Tkinter tutorial

This program shows a simple
menu. It has one command, which
will terminate the program, when
selected.

author: Jan Bodnar
last modified: December 2010
website: www.zetcode.com
"""

from Tkinter import Tk, Frame, Menu


class Example(Frame):

def __init__(self, parent):
Frame.__init__(self, parent)

self.parent = parent
self.initUI()

def initUI(self):

self.parent.title("Simple menu")

menubar = Menu(self.parent)
self.parent.config(menu=menubar)

fileMenu = Menu(menubar)
fileMenu.add_command(label="Exit", command=self.onExit)
menubar.add_cascade(label="File", menu=fileMenu)


def onExit(self):
self.quit()


def main():

root = Tk()
root.geometry("250x150+300+300")
app = Example(root)
root.mainloop()


if __name__ == '__main__':
main()
Our example will show a menu with one item. By selecting the exit menu item we close the application.
menubar = Menu(self.parent)
self.parent.config(menu=menubar)
Here we create a menubar. It is a regular Menu widget configured to be the menubar of the root window.
fileMenu = Menu(menubar)
We create a file menu object. A menu is a popup window containing commands.
fileMenu.add_command(label="Exit", command=self.onExit)
We add a command to the file menu. The command will call the onExit() method.
menubar.add_cascade(label="File", menu=fileMenu)
The file menu is added to the menubar.
Simple menu
Figure: Simple menu

Submenu

A submenu is a menu plugged into another menu object. The next example demonstrates this.
#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
ZetCode Tkinter tutorial

In this script we create a submenu
a separator and keyboard shortcuts to menus.

author: Jan Bodnar
last modified: December 2010
website: www.zetcode.com
"""

from Tkinter import Tk, Frame, Menu


class Example(Frame):

def __init__(self, parent):
Frame.__init__(self, parent)

self.parent = parent

self.initUI()

def initUI(self):

self.parent.title("Submenu")

menubar = Menu(self.parent)
self.parent.config(menu=menubar)

fileMenu = Menu(menubar)

submenu = Menu(fileMenu)
submenu.add_command(label="New feed")
submenu.add_command(label="Bookmarks")
submenu.add_command(label="Mail")
fileMenu.add_cascade(label='Import', menu=submenu, underline=0)

fileMenu.add_separator()

fileMenu.add_command(label="Exit", underline=0, command=self.onExit)
menubar.add_cascade(label="File", underline=0, menu=fileMenu)


def onExit(self):
self.quit()


def main():

root = Tk()
root.geometry("250x150+300+300")
app = Example(root)
root.mainloop()


if __name__ == '__main__':
main()
In the example, we have three options in a submenu of a file menu. We create a separator and keyboard shortcuts.
submenu = Menu(fileMenu)
submenu.add_command(label="New feed")
submenu.add_command(label="Bookmarks")
submenu.add_command(label="Mail")
We have a submenu with three commands. The submenu is a regular menu.
fileMenu.add_cascade(label='Import', menu=submenu, underline=0)
By adding the menu to the fileMenu and not to the menubar, we create a submenu. The underline parameter creates a keyboard shortcut. We provide a character position, which should be underlined. In our case it is the first. Positions start from zero. When we click on the File menu, a popup window is shown. The Import menu has one character underlined. We can select it either with the mouse pointer, or with the Alt + I shortcut.
fileMenu.add_separator()
A separator is a horizontal line that visually separates the menu commands. This way we can group items into some logical places.
Submenu
Figure: Submenu

Popup menu

In the next example, we create a popup menu. Popup menu is also called a context menu. It can be shown anywhere on the client area of a window.
#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
ZetCode Tkinter tutorial

In this program, we create
a popup menu.

author: Jan Bodnar
last modified: December 2010
website: www.zetcode.com
"""

from Tkinter import Tk, Frame, Menu


class Example(Frame):

def __init__(self, parent):
Frame.__init__(self, parent)

self.parent = parent

self.initUI()

def initUI(self):

self.parent.title("Popup menu")
self.menu = Menu(self.parent, tearoff=0)
self.menu.add_command(label="Beep", command=self.bell())
self.menu.add_command(label="Exit", command=self.onExit)

self.parent.bind("<Button-3>", self.showMenu)
self.pack()


def showMenu(self, e):
self.menu.post(e.x_root, e.y_root)


def onExit(self):
self.quit()


def main():

root = Tk()
root.geometry("250x150+300+300")
app = Example(root)
root.mainloop()


if __name__ == '__main__':
main()
In our example, we create a popup menu with two commands.
self.menu = Menu(self.parent, tearoff=0)
A context menu is a regular Menu widget. The tearoff feature is turned off. Now it is not possible to separate the menu into a new toplevel window.
self.parent.bind("<Button-3>", self.showMenu)
We bind the <Button-3> event to the showMenu() method. The event is generated when we right click on the client area of the window.
def showMenu(self, e):
self.menu.post(e.x_root, e.y_root)
The showMenu() method shows the context menu. The popup menu is shown at the x, y coordinates of the mouse click.
Popup menu`
Figure: Popup menu

Toolbar

Menus group commands that we can use in an application. Toolbars provide a quick access to the most frequently used commands. There is no toolbar widget in Tkinter.
#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
ZetCode Tkinter tutorial

In this program, we create a toolbar.

author: Jan Bodnar
last modified: December 2010
website: www.zetcode.com
"""

from PIL import Image, ImageTk
from Tkinter import Tk, Frame, Menu
from Tkinter import Button, LEFT, TOP, X, FLAT, RAISED



class Example(Frame):

def __init__(self, parent):
Frame.__init__(self, parent)

self.parent = parent

self.initUI()

def initUI(self):

self.parent.title("Toolbar")

menubar = Menu(self.parent)
self.fileMenu = Menu(self.parent, tearoff=0)
self.fileMenu.add_command(label="Exit", command=self.onExit)
menubar.add_cascade(label="File", menu=self.fileMenu)

toolbar = Frame(self.parent, bd=1, relief=RAISED)

self.img = Image.open("exit.png")
eimg = ImageTk.PhotoImage(self.img)

exitButton = Button(toolbar, image=eimg, relief=FLAT,
command=self.quit)
exitButton.image = eimg
exitButton.pack(side=LEFT, padx=2, pady=2)

toolbar.pack(side=TOP, fill=X)
self.parent.config(menu=menubar)
self.pack()


def onExit(self):
self.quit()


def main():

root = Tk()
root.geometry("250x150+300+300")
app = Example(root)
root.mainloop()


if __name__ == '__main__':
main()
Our toolbar will be a frame on which we will put a button.
toolbar = Frame(self.parent, bd=1, relief=RAISED)
A toolbar is created. It is a Frame. We created a raised border, so that the boundaries of a toolbar are visible.
self.img = Image.open("exit.png")
eimg = ImageTk.PhotoImage(self.img)
Image and a photo image for the toolbar button are created.
exitButton = Button(toolbar, image=tatras, relief=FLAT,
command=self.quit)
Button widget is created.
exitButton.pack(side=LEFT, padx=2, pady=2)
The toolbar is a frame and a frame is a container widget. We pack the button to the left side. We add some padding.
toolbar.pack(side=TOP, fill=X)
The toolbar itself is packed to the top of the toplevel window. It is horizontally stretched.
Toolbar
Figure: Toolbar
In this part of the Tkinter tutorial, we mentioned menus and toolbars.
Continue Reading

Widgets in Tkinter Programming

Widgets

In this part of the Tkinter tutorial, we will cover some basic Tkinter widgets.
Widgets are basic building blocks of a GUI application. Over the years, several widgets became a standard in all toolkits on all OS platforms. For example a button, a check box or a scroll bar. Some of them might have a different name. For instance, a check box is called a check button in Tkinter. Tkinter has a small set of widgets which cover the basic programming needs. More specialized components can be created as custom widgets.

Checkbutton

The Checkbutton is a widget, that has two states. On and Off. The On state is visualized by a check mark. It is used to denote some boolean property. The Checkbutton widget provides a check box with a text label.
#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
ZetCode Tkinter tutorial

This program toggles the title of the
window with the Checkbutton widget

author: Jan Bodnar
last modified: December 2010
website: www.zetcode.com
"""


from Tkinter import Tk, Frame, Checkbutton
from Tkinter import IntVar, BOTH


class Example(Frame):

def __init__(self, parent):
Frame.__init__(self, parent)

self.parent = parent
self.initUI()

def initUI(self):

self.parent.title("Checkbutton")

self.pack(fill=BOTH, expand=1)
self.var = IntVar()

cb = Checkbutton(self, text="Show title",
variable=self.var, command=self.onClick)
cb.select()
cb.place(x=50, y=50)


def onClick(self):

if self.var.get() == 1:
self.master.title("Checkbutton")
else:
self.master.title("")


def main():

root = Tk()
root.geometry("250x150+300+300")
app = Example(root)
root.mainloop()


if __name__ == '__main__':
main()

In our example, we place a check button on the window. The check button shows/hides the title of the window.
self.var = IntVar()
We create an IntVar object. It is a value holder for integer values for widgets in Tkinter.
cb = Checkbutton(self, text="Show title",
variable=self.var, command=self.onClick)
An instance of the Checkbutton is created. The value holder is connected to the widget via the variable parameter. When we click on the check button, the onClick() method is called. This is done with the command parameter.
cb.select()
Initially, the title is shown in the titlebar. So at the start, we make it checked with the select() method.
if self.var.get() == 1:
self.master.title("Checkbutton")
else:
self.master.title("")
Inside the onClick() method, we display or hide the title based on the value from the self.var variable.
Checkbutton
Figure: Checkbutton

Label

The Label widget is used to display text or images. No user interaction is available.
sudo apt-get install python-imaging-tk
In order to run this example, we must install python-imaging-tk module.
#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
ZetCode Tkinter tutorial

In this script, we use the Label
widget to show an image.

author: Jan Bodnar
last modified: December 2010
website: www.zetcode.com
"""


from PIL import Image, ImageTk
from Tkinter import Tk, Frame, Label


class Example(Frame):

def __init__(self, parent):
Frame.__init__(self, parent)

self.parent = parent
self.initUI()

def initUI(self):

self.parent.title("Label")

self.img = Image.open("tatras.jpg")
tatras = ImageTk.PhotoImage(self.img)
label = Label(self, image=tatras)

label.image = tatras
label.pack()

self.pack()

def setGeometry(self):

w, h = self.img.size
self.parent.geometry(("%dx%d+300+300") % (w, h))


def main():

root = Tk()
ex = Example(root)
ex.setGeometry()
root.mainloop()


if __name__ == '__main__':
main()
Our example shows an image on the window.
from PIL import Image, ImageTk
By default, the Label widget can display only a limited set of image types. To display a jpg image, we must use the PIL, Python Imaging Library module.
self.img = Image.open("tatras.jpg")
tatras = ImageTk.PhotoImage(self.img)
We create an image from the image file in the current working directory. Later we create a photo image from the image.
label = Label(self, image=tatras)
The photoimage is given to the image parameter of the label widget.
label.image = tatras
In order not to be garbage collected, the image reference must be stored.
w, h = self.img.size
self.parent.geometry(("%dx%d+300+300") % (w, h))
We make the size of the window to exactly fit the image size.

Scale

Scale is a widget that lets the user graphically select a value by sliding a knob within a bounded interval. Our example will show a selected number in a label widget.
#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
ZetCode Tkinter tutorial

In this script, we show how to
use the Scale widget.

author: Jan Bodnar
last modified: December 2010
website: www.zetcode.com
"""

from ttk import Frame, Label, Scale, Style
from Tkinter import Tk, BOTH, IntVar


class Example(Frame):

def __init__(self, parent):
Frame.__init__(self, parent)

self.parent = parent
self.initUI()

def initUI(self):

self.parent.title("Scale")
self.style = Style()
self.style.theme_use("default")

self.pack(fill=BOTH, expand=1)

scale = Scale(self, from_=0, to=100,
command=self.onScale)
scale.place(x=20, y=20)

self.var = IntVar()
self.label = Label(self, text=0, textvariable=self.var)
self.label.place(x=130, y=70)

def onScale(self, val):

v = int(float(val))
self.var.set(v)


def main():

root = Tk()
ex = Example(root)
root.geometry("300x150+300+300")
root.mainloop()


if __name__ == '__main__':
main()
We have two widgets in the above script. A scale and a label. A value from the scale widget is shown in the label widget.
scale = Scale(self, from_=0, to=100, 
command=self.onScale)
Scale widget is created. We provide the lower and upper bounds. The from is a regular Python keyword, that is why there is an underscore after the first parameter. When we move the knob of the scale, the onScale() method is called.
self.var = IntVar()
self.label = Label(self, text=0, textvariable=self.var)
An integer value holder and label widget are created. Value from the holder is shown in the label widget.
def onScale(self, val):

v = int(float(val))
self.var.set(v)
The onScale() method receives a currently selected value from the scale widget as a parameter. The value is first converted to a float and then to integer. Finally, the value is set to the value holder of the label widget.
Scale
Figure: Scale

Listbox

Listbox is a widget that displays a list of objects. It allows the user to select one or more items.
#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
ZetCode Tkinter tutorial

In this script, we show how to
use the Listbox widget.

author: Jan Bodar
last modified: December 2010
website: www.zetcode.com
"""

from ttk import Frame, Label, Style
from Tkinter import Tk, BOTH, Listbox, StringVar, END


class Example(Frame):

def __init__(self, parent):
Frame.__init__(self, parent)

self.parent = parent
self.initUI()

def initUI(self):

self.parent.title("Listbox")

self.pack(fill=BOTH, expand=1)

acts = ['Scarlett Johansson', 'Rachel Weiss',
'Natalie Portman', 'Jessica Alba']

lb = Listbox(self)
for i in acts:
lb.insert(END, i)

lb.bind("<<ListboxSelect>>", self.onSelect)

lb.place(x=20, y=20)

self.var = StringVar()
self.label = Label(self, text=0, textvariable=self.var)
self.label.place(x=20, y=210)

def onSelect(self, val):

sender = val.widget
idx = sender.curselection()
value = sender.get(idx)

self.var.set(value)


def main():

root = Tk()
ex = Example(root)
root.geometry("300x250+300+300")
root.mainloop()


if __name__ == '__main__':
main()
In our example, we show a list of actresses in the Listbox. The currently selected actress is displayed in a label widget.
acts = ['Scarlett Johansson', 'Rachel Weiss', 
'Natalie Portman', 'Jessica Alba']
This is a list of actresses to be shown in the listbox.
lb = Listbox(self)
for i in acts:
lb.insert(END, i)
We create an instance of the Listbox and insert all the items from the above mentioned list.
lb.bind("<<ListboxSelect>>", self.onSelect)    
When we select an item in the listbox, the <<ListboxSelect>> event is generated. We bind the onSelect() method to this event.
self.var = StringVar()
self.label = Label(self, text=0, textvariable=self.var)
A label and its value holder is created. In this label we will display the currently selected item.
sender = val.widget
We get the sender of the event. It is our listbox widget.
idx = sender.curselection()
We find out the index of the selected item using the curselection() method.
value = sender.get(idx)  
The actual value is retrieved with the get() method, which takes the index of the item.
self.var.set(value)
Finally, the label is updated.
Listbox widget
Figure: Listbox widget
In this part of the Tkinter tutorial, we have presented several Tkinter widgets.
Continue Reading

Layout management in Tkinter

Layout management in Tkinter

In this part of the Tkinter programming tutorial, we will introduce layout managers.
When we design the GUI of our application, we decide what widgets we will use and how we will organize those widgets in the application. To organize our widgets, we use specialized non visible objects called layout managers.
There are two kinds of widgets. Containers and their children. The containers group their children into suitable layouts.
Tkinter has three built-in layout managers. The pack, grid and place managers. The pack geometry manager organizes widgets in vertical and horizontal boxes. The grid geometry managers places widgets in a two dimensional grid. Finally, the place geometry manager places widgets on their containers using absolute positioning.

Absolute positioning

In most cases, programmers should use layout managers. There are a few situations, where we can use absolute positioning. In absolute positioning, the programmer specifies the position and the size of each widget in pixels. The size and the position of a widget do not change, if you resize a window. Applications look different on various platforms, and what looks OK on Linux, might not look OK on Mac. Changing fonts in your application might spoil the layout. If you translate your application into another language, you must redo your layout.
#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
ZetCode Tkinter tutorial

In this script, we lay out images
using absolute positioning.

author: Jan Bodnar
last modified: December 2010
website: www.zetcode.com
"""

from PIL import Image, ImageTk
from Tkinter import Tk, Label, BOTH
from ttk import Frame, Style

class Example(Frame):

def __init__(self, parent):
Frame.__init__(self, parent)

self.parent = parent

self.initUI()

def initUI(self):

self.parent.title("Absolute positioning")
self.pack(fill=BOTH, expand=1)

Style().configure("TFrame", background="#333")

bard = Image.open("bardejov.jpg")
bardejov = ImageTk.PhotoImage(bard)
label1 = Label(self, image=bardejov)
label1.image = bardejov
label1.place(x=20, y=20)

rot = Image.open("rotunda.jpg")
rotunda = ImageTk.PhotoImage(rot)
label2 = Label(self, image=rotunda)
label2.image = rotunda
label2.place(x=40, y=160)

minc = Image.open("mincol.jpg")
mincol = ImageTk.PhotoImage(minc)
label3 = Label(self, image=mincol)
label3.image = mincol
label3.place(x=170, y=50)


def main():

root = Tk()
root.geometry("300x280+300+300")
app = Example(root)
root.mainloop()


if __name__ == '__main__':
main()
In this example, we place three images using absolute positioning. We will use the place geometry manager.
from PIL import Image, ImageTk
We will use Image and ImageTk from the Python Imaging Library (PIL) module.
Style().configure("TFrame", background="#333")
We configure our frame to have a dark gray background using styles.
bard = Image.open("bardejov.jpg")
bardejov = ImageTk.PhotoImage(bard)
We create an image object and a photo image object from an image in the current working directory.
label1 = Label(self, image=bardejov)
We create a Label with an image. Labels can contain text or images.
label1.image = bardejov
We must keep the reference to the image to prevent image from being garbage collected.
label1.place(x=20, y=20)
The label is placed on the frame at x=20, y=20 coordinates.
Absolute
Figure: Absolute positioning

Buttons example

In the following example, we will position two buttons in the bottom right corner of the window. We will use the pack manager.
#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
ZetCode Tkinter tutorial

In this script, we use pack manager
to position two buttons in the
bottom right corner of the window.

author: Jan Bodnar
last modified: December 2010
website: www.zetcode.com
"""

from Tkinter import Tk, RIGHT, BOTH, RAISED
from ttk import Frame, Button, Style


class Example(Frame):

def __init__(self, parent):
Frame.__init__(self, parent)

self.parent = parent

self.initUI()

def initUI(self):

self.parent.title("Buttons")
self.style = Style()
self.style.theme_use("default")

frame = Frame(self, relief=RAISED, borderwidth=1)
frame.pack(fill=BOTH, expand=1)

self.pack(fill=BOTH, expand=1)

closeButton = Button(self, text="Close")
closeButton.pack(side=RIGHT, padx=5, pady=5)
okButton = Button(self, text="OK")
okButton.pack(side=RIGHT)


def main():

root = Tk()
root.geometry("300x200+300+300")
app = Example(root)
root.mainloop()


if __name__ == '__main__':
main()
We will have two frames. There is the base frame and an additional frame, which will expand in both directions and push the two buttons to the bottom of the base frame. The buttons are placed in a horizontal box and placed to the right of this box.
frame = Frame(self, relief=RAISED, borderwidth=1)
frame.pack(fill=BOTH, expand=1)
We create another Frame widget. This widget takes the bulk of the area. We change the border of the frame so that the frame is visible. By default it is flat.
closeButton = Button(self, text="Close")
closeButton.pack(side=RIGHT, padx=5, pady=5)
A closeButton is created. It is put into a horizontal box. The side parameter will create a horizontal box layout, in which the button is placed to the right of the box. The padxand the pady parameters will put some space between the widgets. The padx puts some space between the button widgets and between the closeButton and the right border of the root window. The pady puts some space between the button widgets and the borders of the frame and the root window.
okButton.pack(side=RIGHT)
The okButton is placed next to the closeButton. With 5px space between them.
Buttons example
Figure: Buttons example

Calculator

We will use a Tkinter grid geometry manager to create a skeleton of a calculator.
#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
ZetCode Tkinter tutorial

In this script, we use the grid manager
to create a skeleton of a calculator.

author: Jan Bodnar
last modified: December 2010
website: www.zetcode.com
"""

from Tkinter import Tk, W, E
from ttk import Frame, Button, Label, Style
from ttk import Entry


class Example(Frame):

def __init__(self, parent):
Frame.__init__(self, parent)

self.parent = parent

self.initUI()

def initUI(self):

self.parent.title("Calculator")

Style().configure("TButton", padding=(0, 5, 0, 5),
font='serif 10')

self.columnconfigure(0, pad=3)
self.columnconfigure(1, pad=3)
self.columnconfigure(2, pad=3)
self.columnconfigure(3, pad=3)

self.rowconfigure(0, pad=3)
self.rowconfigure(1, pad=3)
self.rowconfigure(2, pad=3)
self.rowconfigure(3, pad=3)
self.rowconfigure(4, pad=3)

entry = Entry(self)
entry.grid(row=0, columnspan=4, sticky=W+E)
cls = Button(self, text="Cls")
cls.grid(row=1, column=0)
bck = Button(self, text="Back")
bck.grid(row=1, column=1)
lbl = Button(self)
lbl.grid(row=1, column=2)
clo = Button(self, text="Close")
clo.grid(row=1, column=3)
sev = Button(self, text="7")
sev.grid(row=2, column=0)
eig = Button(self, text="8")
eig.grid(row=2, column=1)
nin = Button(self, text="9")
nin.grid(row=2, column=2)
div = Button(self, text="/")
div.grid(row=2, column=3)

fou = Button(self, text="4")
fou.grid(row=3, column=0)
fiv = Button(self, text="5")
fiv.grid(row=3, column=1)
six = Button(self, text="6")
six.grid(row=3, column=2)
mul = Button(self, text="*")
mul.grid(row=3, column=3)

one = Button(self, text="1")
one.grid(row=4, column=0)
two = Button(self, text="2")
two.grid(row=4, column=1)
thr = Button(self, text="3")
thr.grid(row=4, column=2)
mns = Button(self, text="-")
mns.grid(row=4, column=3)

zer = Button(self, text="0")
zer.grid(row=5, column=0)
dot = Button(self, text=".")
dot.grid(row=5, column=1)
equ = Button(self, text="=")
equ.grid(row=5, column=2)
pls = Button(self, text="+")
pls.grid(row=5, column=3)

self.pack()

def main():

root = Tk()
app = Example(root)
root.mainloop()


if __name__ == '__main__':
main()
The grid manager is used to organize buttons in the frame container widget.
Style().configure("TButton", padding=(0, 5, 0, 5), 
font='serif 10')
We configure the Button widget to have a specific font and to have some internal padding.
self.columnconfigure(0, pad=3)
...
self.rowconfigure(0, pad=3)
We use the columnconfigure() and the rowconfigure()methods to define some space in grid columns and rows. This way we achieve that the buttons are separated by some space.
entry = Entry(self)
entry.grid(row=0, columnspan=4, sticky=W+E)
The Entry widget is where the digits are displayed. The widget is placed at the first row and it will span all four columns. Widgets may not occupy all the space allotted by cells in the grid. The stickyparameter will expand the widget in a given direction. In our case, we ensure, that the entry widget is expanded from left to the right.
cls = Button(self, text="Cls")
cls.grid(row=1, column=0)
The cls button is placed at the second row, first column. Note that the rows and columns start at zero.
self.pack()
The pack() method shows the frame widget and gives it initial size. If no other parameters are given, the size will be just enough to show all children. This method packs the frame widget to the toplevel root window, which is also a container. The grid geometry manager is used to organize buttons in the frame widget.
Calculator
Figure: Calculator

Windows example

The following example creates the windows dialog using the grid geometry manager. The dialog comes from the JDeveloper application.
#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
ZetCode Tkinter tutorial

In this script, we use the grid
manager to create a more complicated
layout.

author: Jan Bodnar
last modified: December 2010
website: www.zetcode.com
"""

from Tkinter import Tk, Text, BOTH, W, N, E, S
from ttk import Frame, Button, Label, Style


class Example(Frame):

def __init__(self, parent):
Frame.__init__(self, parent)

self.parent = parent

self.initUI()

def initUI(self):

self.parent.title("Windows")
self.style = Style()
self.style.theme_use("default")
self.pack(fill=BOTH, expand=1)

self.columnconfigure(1, weight=1)
self.columnconfigure(3, pad=7)
self.rowconfigure(3, weight=1)
self.rowconfigure(5, pad=7)

lbl = Label(self, text="Windows")
lbl.grid(sticky=W, pady=4, padx=5)

area = Text(self)
area.grid(row=1, column=0, columnspan=2, rowspan=4,
padx=5, sticky=E+W+S+N)

abtn = Button(self, text="Activate")
abtn.grid(row=1, column=3)

cbtn = Button(self, text="Close")
cbtn.grid(row=2, column=3, pady=4)

hbtn = Button(self, text="Help")
hbtn.grid(row=5, column=0, padx=5)

obtn = Button(self, text="OK")
obtn.grid(row=5, column=3)


def main():

root = Tk()
root.geometry("350x300+300+300")
app = Example(root)
root.mainloop()


if __name__ == '__main__':
main()
In this example, we will use a Label widget, a Text widget and four buttons.
self.columnconfigure(1, weight=1)
self.columnconfigure(3, pad=7)
self.rowconfigure(3, weight=1)
self.rowconfigure(5, pad=7)
We define some spaces among widgets in the grid. The largest space is put between the Text widget and the buttons.
lbl = Label(self, text="Windows")
lbl.grid(sticky=W, pady=4, padx=5)
The label widget is created and put into the grid. If no column and row is specified, then the first column/row is assumed. The label sticks to west and it has some padding around its text.
area = Text(self)
area.grid(row=1, column=0, columnspan=2, rowspan=4,
padx=5, sticky=E+W+S+N)
The Text widget is created and starts from the second row, first column. It spans 2 columns and 4 rows. There is 4px space between the widget and the left border of the root window. Finally, it sticks to all the four sides. So when the window is resized, the Text widget grows in all directions.
Windows example
Figure: Windows example
In this part of the Tkinter tutorial, we mentioned layout management of widgets.
Continue Reading

Introduction to Tkinter Programming Tutorial

Introduction to Tkinter

In this part of the Tkinter tutorial, we will introduce the Tkinter toolkit and create our first programs.
The purpose of this tutorial is to get you started with the Tkinter toolkit. Images used in this tutorial can be downloaded here. I used some icons from the Tango icons pack of the Gnome project.

Tkinter

Tkinter is a Python binding to the Tk GUI toolkit. Tk is the original GUI library for the Tcl language. Tkinter is implemented as a Python wrapper around a complete Tcl interpreter embedded in the Python interpreter. There are several other popular Python GUI toolkits. Most popular are wxPython, PyQt and PyGTK.

Python

python logo Python is a general-purpose, dynamic, object-oriented programming language. The design purpose of the Python language emphasizes programmer productivity and code readability. Python was initially developed by Guido van Rossum. It was first released in 1991. Python was inspired by ABC, Haskell, Java, Lisp, Icon and Perl programming languages. Python is a high level, general purpose, multiplatform, interpreted language. Python is a minimalistic language. One of its most visible features is that it does not use semicolons nor brackets. Python uses indentation instead. There are two main branches of Python currently. Python 2.x and Python 3.x. Python 3.x breaks backward compatibility with previous releases of Python. It was created to correct some design flaws of the language and make the language more clean. The most recent version of Python 2.x is 2.7.1, and of Python 3.x 3.1.3. This tutorial is written in Python 2.x. Most of the code is written in Python 2.x versions. It will take some time till the software base and programmers will migrate to Python 3.x. Today, Python is maintained by a large group of volunteers worldwide. Python is open source software.
Python is an ideal start for those, who want to learn programming.
Python programming language supports several programming styles. It does not force a programmer to a specific paradigm. Python supports object oriented and procedural programming. There is also a limited support for functional programming.
The official web site for the Python programming language is python.org

Simple example

In our first example, we will show a basic window on the screen.
#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
ZetCode Tkinter tutorial

This script shows a simple window
on the screen.

author: Jan Bodnar
last modified: January 2011
website: www.zetcode.com
"""

from Tkinter import Tk, Frame, BOTH


class Example(Frame):

def __init__(self, parent):
Frame.__init__(self, parent, background="white")

self.parent = parent

self.initUI()

def initUI(self):

self.parent.title("Simple")
self.pack(fill=BOTH, expand=1)


def main():

root = Tk()
root.geometry("250x150+300+300")
app = Example(root)
root.mainloop()


if __name__ == '__main__':
main()
While this code is very small, the application window can do quite a lot. It can be resized, maximized, minimized. All the complexity that comes with it has been hidden from the application programmer.
from Tkinter import Tk, Frame
Here we import Tk and Frame classes. The first class is used to create a root window. The latter is a container for other widgets.
class Example(Frame):

def __init__(self, parent):
Frame.__init__(self, parent, background="white")
Our example class inherits from the Frame container widget. In the __init__() constructor method we call the constructor of our inherited class. The background parameter specifies the background color of the Frame widget.
self.parent = parent
We save a reference to the parent widget. The parent widget is the Tk root window in our case.
self.initUI()
We delegate the creation of the user interface to the initUI() method.
self.parent.title("Simple")
We set the title of the window using the title() method.
self.pack(fill=BOTH, expand=1)
The pack() method is one of the three geometry managers in Tkinter. It organizes widgets into horizontal and vertical boxes. Here we put the Frame widget, accessed via the self attribute to the Tk root window. It is expanded in both directions. In other words, it takes the whole client space of the root window.
root = Tk()
The root window is created. The root window is a main application window in our programs. It has a title bar and borders. These are provided by the window manager. It must be created before any other widgets.
root.geometry("250x150+300+300")
The geometry() method sets a size for the window and positions it on the screen. The first two parameters are width and height of the window. The last two parameters are x, y screen coordinates.
app = Example(root)
Here we create the instance of the application class.
root.mainloop()  
Finally, we enter the mainloop. The event handling starts from this point. The mainloop receives events from the window system and dispatches them to the application widgets. It is terminated when we click on the close button of the titlebar or call the quit() method.
Simple
Figure: Simple window

Centering window

This script centers a window on the screen.
#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
ZetCode Tkinter tutorial

This script centers a small
window on the screen.

author: Jan Bodnar
last modified: January 2011
website: www.zetcode.com
"""

from Tkinter import Tk, Frame, BOTH



class Example(Frame):

def __init__(self, parent):
Frame.__init__(self, parent, background="white")

self.parent = parent
self.parent.title("Centered window")
self.pack(fill=BOTH, expand=1)
self.centerWindow()

def centerWindow(self):

w = 290
h = 150

sw = self.parent.winfo_screenwidth()
sh = self.parent.winfo_screenheight()

x = (sw - w)/2
y = (sh - h)/2
self.parent.geometry('%dx%d+%d+%d' % (w, h, x, y))

def main():

root = Tk()
ex = Example(root)
root.mainloop()


if __name__ == '__main__':
main()
We need to have the size of the window and the size of the screen to position the window in the center of the monitor screen.
w = 290
h = 150
These are the width and height values of the application window.
sw = self.parent.winfo_screenwidth()
sh = self.parent.winfo_screenheight()
We determine the width and height of the screen.
x = (sw - w)/2
y = (sh - h)/2
We calculate the required x, y coordinates.
self.parent.geometry('%dx%d+%d+%d' % (w, h, x, y))
Finally, the geometry() method is used to place the window in the center of the screen.

Quit button

In the last example of this section, we will create a quit button. When we press this button, the application terminates.
#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
ZetCode Tkinter tutorial

This program creates a quit
button. When we press the button,
the application terminates.

author: Jan Bodnar
last modified: December 2010
website: www.zetcode.com
"""

from Tkinter import Tk, BOTH
from ttk import Frame, Button, Style


class Example(Frame):

def __init__(self, parent):
Frame.__init__(self, parent)

self.parent = parent

self.initUI()

def initUI(self):

self.parent.title("Quit button")
self.style = Style()
self.style.theme_use("default")

self.pack(fill=BOTH, expand=1)

quitButton = Button(self, text="Quit",
command=self.quit)
quitButton.place(x=50, y=50)


def main():

root = Tk()
root.geometry("250x150+300+300")
app = Example(root)
root.mainloop()


if __name__ == '__main__':
main()
We position a Button on the window. Clicking on the button will terminate the application.
from ttk import Frame, Button, Style
Tkinter supports theming of widgets. Widgets that are themed can be imported from the ttk module. At the time of this writing, not all widgets are themable. For instance, menus or listboxes are not supported so far.
self.style = Style()
self.style.theme_use("default")
We apply a theme for our widgets. Some of the supported themes are clam, default, alt or classic.
quitButton = Button(self, text="Quit",
command=self.quit)
We create an instance of the Button widget. The parent of this button is the Frame container. We provide a label for the button and a command. The command specifies a method that is called when we press the button. In our case the quit() method is called, which terminates the application.
quitButton.place(x=50, y=50)
We use the place geometry manager to position the button in absolute coordinates. 50x50px from the top-left corner of the window.
Quit button
Figure: Quit button
This section was an introduction to the Tkinter toolkit.
Continue Reading