• No results found

Python Crash Course: GUIs with Tkinter

N/A
N/A
Protected

Academic year: 2021

Share "Python Crash Course: GUIs with Tkinter"

Copied!
40
0
0

Loading.... (view fulltext now)

Full text

(1)

Python Crash Course: GUIs with Tkinter

Do you train for passing tests

or do you train for creative inquiry?

Noam Chomsky

Steffen Brinkmann

Max-Planck-Institut f¨

ur Astronomie, Heidelberg

IMPRESS, 2016

(2)

The ingredients

I

A working Python installation

I

Internet connection

I

Passion for Python

(3)

Outline

Motivation

To GUI or not to GUI

Getting started

Terminology

Hello World

The Widgets

Overview

Widget Properties and Placement

Putting it together

(4)

Motivation

To GUI or not to GUI

Outline

Motivation

To GUI or not to GUI

Getting started

Terminology

Hello World

The Widgets

Overview

Widget Properties and Placement

Putting it together

(5)

Motivation

To GUI or not to GUI

Why use GUIs?

I

Users are used to GUIs

I

Easy interaction

I

Display images, animations etc.

I

Visualise workflow

(6)

Motivation

To GUI or not to GUI

Why not use GUIs?

I

Faster development

I

Faster execution

I

Easier to test

I

Can be included in scripts (pipelines)

(7)

Motivation

To GUI or not to GUI

Why Tkinter?

I

Tkinter is the standard Python interface to the Tk GUI

toolkit.

I

No need to install additional packages

I

Simple enough to get quick results

I

Powerful enough for most applications

(8)

Motivation

To GUI or not to GUI

Get help

I

http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/index.html

(9)

Getting started

Terminology

Outline

Motivation

To GUI or not to GUI

Getting started

Terminology

Hello World

The Widgets

Overview

Widget Properties and Placement

Putting it together

(10)

Getting started

Terminology

Terminology

I

Widget:

Visual element of interaction. Can be a container

(see below), control (Button, slider, . . . ), a display (label,

canvas,. . . ) or a combination of both (Text field, spin box)

I

Box, Container:

Widget that can contain one or more other

widgets.

(11)

Getting started

Terminology

Terminology

I

Event:

Events are created by the program itself (destroy,

resize, . . . ) or the user via controls (click button, mouse

move,. . . ).

I

Event handler:

Function or method dedicated to react to

events. Typically called on

event

.

I

Event loop:

separate execution thread or process which

checks for new events.

(12)

Getting started

Hello World

Outline

Motivation

To GUI or not to GUI

Getting started

Terminology

Hello World

The Widgets

Overview

Widget Properties and Placement

Putting it together

(13)

Getting started Hello World

Very simple

# !/ bin / env p y t h o n f r o m _ _ f u t u r e _ _ i m p o r t p r i n t _ f u n c t i o n i m p o r t sys if sys.v e r s i o n _ i n f o >= (3 ,): i m p o r t t k i n t e r as tk e l s e: i m p o r t T k i n t e r as tk top = tk.Tk() top.m a i n l o o p()

I

The Tkinter module is called differently in Python 2 and 3

I

The class

Tk

represents the Tkinter framework and is

necessary for the event loop, exiting cleanly etc.

I

The function

mainloop

starts the event loop. It stops when

(14)

Getting started

Hello World

A little less simple

c l a s s H e l l o(tk.F r a m e): def _ _ i n i t _ _(self, m a s t e r=tk.Tk( ) ) : tk.F r a m e._ _ i n i t _ _(self, m a s t e r) s e l f.m a s t e r=m a s t e r s e l f.g r i d() s e l f.c r e a t e W i d g e t s() def c r e a t e W i d g e t s(s e l f): s e l f.b u t t o n 1 = tk.B u t t o n(self, t e x t=" c l i c k me ", c o m m a n d=s e l f.s a y _ h e l l o) s e l f.b u t t o n 1.g r i d(row=10 , c o l u m n= 1 0 ) s e l f.b u t t o n _ q u i t = tk.B u t t o n(self, t e x t=" Q U I T ", fg=" red ", c o m m a n d=s e l f.m a s t e r.d e s t r o y) s e l f.b u t t o n _ q u i t.g r i d(row=20 , c o l u m n= 1 0 ) def s a y _ h e l l o(s e l f): p r i n t(" h e l l o there , e v e r y o n e ! ") app = H e l l o() app.m a i n l o o p()

(15)

Getting started

Hello World

A little less simple

I

It is convenient to create an application class, derived from

tk.Frame

I

Widgets can be added to the application window by

grid()

,

(16)

The Widgets

Overview

Outline

Motivation

To GUI or not to GUI

Getting started

Terminology

Hello World

The Widgets

Overview

Widget Properties and Placement

Putting it together

(17)

The Widgets

Overview

Overview

Frame and Buttons

Frame

The Frame widget is used as a container widget to

organize other widgets.

Button

The Button widget is used to display buttons in your

application.

Checkbutton

The Checkbutton widget is used to display a number of

options as checkboxes. The user can select multiple

options at a time.

Radiobutton

The Radiobutton widget is used to display a number of

options as radio buttons. The user can select only one

option at a time.

(18)

The Widgets

Overview

Overview

Text and Displays

Label

The Label widget is used to provide a single-line caption

for other widgets. It can also contain images.

Message

The Message widget is used to display multiline text fields.

Entry

The Entry widget is used to display a single-line text field

for accepting values from a user.

Spinbox

The Spinbox widget is a variant of the standard Tkinter

Entry widget, which can be used to select from a fixed

number of values.

Text

The Text widget is used to display text in multiple lines.

Canvas

The Canvas widget is used to draw shapes, such as lines,

(19)

The Widgets

Overview

Overview

Menus and more choices and controls

Menubutton

The Menubutton widget is used to display menus in your

application.

Menu

The Menu widget is used to provide various commands to

a user.These commands can be contained inside

Menubutton or set as the main menu.

Listbox

The Listbox widget is used to provide a list of options to a

user.

Scale

The Scale widget is used to provide a slider widget.

Scrollbar

The Scrollbar widget is used to add scrolling

(20)

The Widgets

Overview

Overview

Containers

Toplevel

The Toplevel widget is used to provide a separate window

container.

PanedWindow

A PanedWindow is a container widget that may contain

any number of panes, arranged horizontally or vertically.

LabelFrame

A labelframe is a simple container widget. Its primary

purpose is to act as a spacer or container for complex

window layouts.

(21)

The Widgets

Overview

Overview

Dialogues

tkMessageBox

This module is used to display message boxes in your

applications.

tkFileDialog

This module provides two different pop-up windows you

can use to give the user the ability to find existing files or

create new files.

tkColorChooser

Module featuring a dialogue to select a colour.

(22)

The Widgets

Widget Properties and Placement

Outline

Motivation

To GUI or not to GUI

Getting started

Terminology

Hello World

The Widgets

Overview

Widget Properties and Placement

Putting it together

(23)

The Widgets

Widget Properties and Placement

Setting Widget Properties

During Initialisation

b u t t o n

=

tk

.

B u t t o n

(

parent

,

t e x t

=

’ b u t t o n l a b e l ’

,

c o m m a n d

=

s e l f

.

o n _ b u t t o n

)

I

The only positional argument

parent

specifies in whose grid

the widget will be displayed.

(24)

The Widgets

Widget Properties and Placement

Setting Widget Properties

Using

config()

b u t t o n

=

tk

.

B u t t o n

(

p a r e n t

)

b u t t o n

.

c o n f i g

(

t e x t

=

’ b u t t o n l a b e l ’

)

b u t t o n

.

c o n f i g

(

c o m m a n d

=

s e l f

.

o n _ b u t t o n

)

I

parent

still has to be set when constructing the widget.

I

Options are set as keyword arguments in method

config

:

config(option=value)

I

calling

config()

without arguments returns a dictionary of

all the widget’s current options.

I

The method

cget(option)

returns the value of a single

(25)

The Widgets

Widget Properties and Placement

Setting Widget Properties

Using Widget as Dictionary

b u t t o n

=

tk

.

B u t t o n

(

p a r e n t

)

b u t t o n

[

’ t e x t ’

] =

’ b u t t o n l a b e l ’

b u t t o n

[

’ c o m m a n d ’

] =

s e l f

.

o n _ b u t t o n

I

parent

still has to be set when constructing the widget.

(26)

The Widgets

Widget Properties and Placement

Postioning Widgets

Overview

I

grid()

: Arrange widget on e rectangular grid, i.e. in rows

and columns. Recommended.

I

pack()

: Arrange widgets by stacking them vertically or

horizontally. Very limited.

I

place()

Place widgets at specific coordinates. Most (too

(27)

The Widgets

Widget Properties and Placement

Postioning Widgets

c l a s s H e l l o(tk.F r a m e): def _ _ i n i t _ _(self, m a s t e r=tk.Tk( ) ) : tk.F r a m e._ _ i n i t _ _(self, m a s t e r) s e l f.m a s t e r=m a s t e r s e l f.g r i d() s e l f.c r e a t e W i d g e t s() def c r e a t e W i d g e t s(s e l f): s e l f.b u t t o n 1 = tk.B u t t o n(self, t e x t=" c l i c k me ", c o m m a n d=s e l f.s a y _ h e l l o) s e l f.b u t t o n 1.g r i d(row=10 , c o l u m n= 1 0 ) s e l f.b u t t o n _ q u i t = tk.B u t t o n(self, t e x t=" Q U I T ", fg=" red ", c o m m a n d=s e l f.m a s t e r.d e s t r o y) s e l f.b u t t o n _ q u i t.g r i d(row=20 , c o l u m n= 1 0 ) def s a y _ h e l l o(s e l f): p r i n t(" h e l l o there , e v e r y o n e ! ") app = H e l l o() app.m a i n l o o p()
(28)

The Widgets

Widget Properties and Placement

Postioning Widgets

grid()

I

grid()

places the widget in tk’s geometry manager.

I

Use grid in the top level widget (e.g.

Frame

or other

container) to initialise the grid.

I

Call grid for every widget with the keywords

row

and

column

.

I

Cover more rows and/or columns:

columnspan

,

rowspan

I

Use

sticky

argument to align (e.g.

tk.E

,

tk.NW

) or stretch

(e.g.

tk.N+tk.S

) the widget.

(29)

The Widgets

Widget Properties and Placement

Exercise

Conversion tool

Write a program that converts meter to parsec and vice versa:

(30)

Putting it together

More complexity

Outline

Motivation

To GUI or not to GUI

Getting started

Terminology

Hello World

The Widgets

Overview

Widget Properties and Placement

Putting it together

More complexity

(31)

Putting it together

More complexity

Control Variables

I

Control variables can be

I

tk.StringVar

I

tk.IntVar

I

tk.DoubleVar

I

Get and set values with

get()

and

set()

.

I

Use them to store the Data independently from the visual

(32)

Putting it together

More complexity

Matplotlib in tkinter

I

For simple plot,

tk.Canvas

may suffice

I

For displaying Matplotlib plots in tkinter programs, use

FigureCanvasTkAgg

:

i m p o r t m a t p l o t l i b m a t p l o t l i b.use(’ T k A g g ’)

f r o m m a t p l o t l i b.b a c k e n d s.b a c k e n d _ t k a g g i m p o r t F i g u r e C a n v a s T k A g g

(33)

Putting it together

More complexity

(34)

Putting it together More complexity

Matplotlib in tkinter

f r o m n u m p y i m p o r t * i m p o r t m a t p l o t l i b m a t p l o t l i b.use(’ T k A g g ’) f r o m m a t p l o t l i b.b a c k e n d s.b a c k e n d _ t k a g g i m p o r t F i g u r e C a n v a s T k A g g f r o m m a t p l o t l i b.f i g u r e i m p o r t F i g u r e c l a s s F i t t i n g(tk.F r a m e): def _ _ i n i t _ _(self, m a s t e r=tk.Tk( ) ) : tk.F r a m e._ _ i n i t _ _(self, m a s t e r) s e l f.m a s t e r=m a s t e r s e l f.g r i d() s e l f.c r e a t e V a r i a b l e s() s e l f.c r e a t e W i d g e t s() def c r e a t e V a r i a b l e s(s e l f): s e l f.e _ i n p u t _ t e x t = tk.S t r i n g V a r() s e l f.e _ i n p u t _ t e x t.set(’ sin ( x ) ’)

. . .

(35)

Putting it together More complexity

Matplotlib in tkinter

def c r e a t e W i d g e t s(s e l f): # m a t p l o t l i b F i g u r e C a n v a s T k A g g f = F i g u r e(f i g s i z e=(5 , 4) , dpi= 1 0 0 ) s e l f.sp = f.a d d _ s u b p l o t( 1 1 1 ) s e l f.x = l i n s p a c e( -10 ,10 ,200) x = s e l f.x y = e v a l(s e l f.e _ i n p u t _ t e x t.get()) s e l f.sp.p l o t(x, y) s e l f.c a n v a s = F i g u r e C a n v a s T k A g g(f, m a s t e r=s e l f) s e l f.c a n v a s.s h o w() s e l f.c a n v a s.g e t _ t k _ w i d g e t().g r i d(row = 2 , c o l u m n=10 , c o l u m n s p a n=20 , s t i c k y=tk.N S E W) # e n t r y s e l f.e _ i n p u t = tk.E n t r y(self, t e x t v a r i a b l e=s e l f.e _ i n p u t _ t e x t) s e l f.e _ i n p u t.g r i d(row=5 , c o l u m n=10 , c o l u m n s p a n=20 , s t i c k y=tk.EW) # b u t t o n s s e l f.b _ p l o t = tk.B u t t o n(self, t e x t=" P l o t ", c o m m a n d=s e l f.o n _ p l o t) s e l f.b _ p l o t.g r i d(row=10 , c o l u m n=10 , s t i c k y=tk.EW) s e l f.b _ q u i t = tk.B u t t o n(self, t e x t=" Q u i t ", c o m m a n d=s e l f.m a s t e r.d e s t r o y) s e l f.b _ q u i t.g r i d(row=10 , c o l u m n=20 , s t i c k y=tk.EW) def o n _ p l o t(s e l f): x = s e l f.x y = e v a l(s e l f.e _ i n p u t _ t e x t.get()) s e l f.sp.p l o t(x, y) s e l f.c a n v a s.s h o w() app = F i t t i n g()
(36)

Putting it together

More complexity

Loading files conveniently

I

Let the user choose the file to load using the

tkFileDialog

if sys.v e r s i o n _ i n f o >= (3 ,): f r o m t k i n t e r.f i l e d i a l o g i m p o r t a s k o p e n f i l e n a m e e l s e: f r o m t k F i l e D i a l o g i m p o r t a s k o p e n f i l e n a m e f i l e n a m e _ w i t h _ p a t h = a s k o p e n f i l e n a m e() d a t a = np.l o a d t x t(f i l e n a m e _ w i t h _ p a t h, u n p a c k=T r u e)

I

To let the user choose a filename for saving data (i.e. creating

(37)

Putting it together

More complexity

Menus in tkinter

I

Create menus with

tk.Menu

I

Add items to the menu using

add command()

I

Add a submenu using

add cascade()

.

I

Add a separator using

add separator()

.

I

Finally set the menu as the programs main menu with

(38)

Putting it together More complexity

Menus in tkinter

c l a s s J u s t M e n u(tk.F r a m e): def _ _ i n i t _ _(self, m a s t e r=tk.Tk( ) ) : tk.F r a m e._ _ i n i t _ _(self, m a s t e r) s e l f.m a s t e r=m a s t e r s e l f.c o n f i g(w i d t h= 3 0 0 ) s e l f.c o n f i g(h e i g h t= 2 0 0 ) s e l f.g r i d() s e l f.c r e a t e M e n u() def c r e a t e M e n u(s e l f): m e n u b a r = tk.M e n u(s e l f.m a s t e r) f i l e m e n u = tk.M e n u(menubar, t e a r o f f=1) f i l e m e n u.a d d _ c o m m a n d(l a b e l=" New ", c o m m a n d=s e l f.d o n o t h i n g, u n d e r l i n e=0) f i l e m e n u.a d d _ c o m m a n d(l a b e l=" O p e n ", c o m m a n d=s e l f.d o n o t h i n g) f i l e m e n u.a d d _ c o m m a n d(l a b e l=" S a v e ", c o m m a n d=s e l f.d o n o t h i n g) f i l e m e n u.a d d _ c o m m a n d(l a b e l=" S a v e as ... ", c o m m a n d=s e l f.d o n o t h i n g) f i l e m e n u.a d d _ c o m m a n d(l a b e l=" C l o s e ", c o m m a n d=s e l f.d o n o t h i n g) f i l e m e n u.a d d _ s e p a r a t o r() f i l e m e n u.a d d _ c o m m a n d(l a b e l=" E x i t ", c o m m a n d=s e l f.m a s t e r.q u i t) m e n u b a r.a d d _ c a s c a d e(l a b e l=" F i l e ", m e n u=f i l e m e n u, u n d e r l i n e=0) s e l f.m a s t e r.c o n f i g(m e n u=m e n u b a r) def d o n o t h i n g(s e l f): p r i n t(’ do n o t h i n g ’) app = J u s t M e n u()
(39)

Putting it together

More complexity

Exercise

I

Download the data file:

www.mpia.da/˜ brinkmann/PythonCrash/fitting.dat

I

Write a program that implements a button to load and display

the data in a plot.

I

Extend this program to feature three slide controls

(

tk.Scale

), which control a, b and c in this function

def m o d e l(x,a,b,c):

r e t u r n a*x**2 + b*x + c

I

Plot the parabola in the same axes as the data. It should

update whenever the slide controls are changed.

(40)

Appendix

For Further Reading

For Further Reading I

J. E. Grayson

Python and Tkinter Programming

.

Manning Publications, 2000.

B. Chaudhary

Tkinter GUI Application Development

.

Packt Publishing, 2013.

References

Related documents