- •Introduction
- •Introduction - What, Why, Who etc.
- •Why am I writing this?
- •What will I cover
- •Who should read it?
- •Why Python?
- •Other resources
- •Concepts
- •What do I need?
- •Generally
- •Python
- •QBASIC
- •What is Programming?
- •Back to BASICs
- •Let me say that again
- •A little history
- •The common features of all programs
- •Let's clear up some terminology
- •The structure of a program
- •Batch programs
- •Event driven programs
- •Getting Started
- •A word about error messages
- •The Basics
- •Simple Sequences
- •>>> print 'Hello there!'
- •>>>print 6 + 5
- •>>>print 'The total is: ', 23+45
- •>>>import sys
- •>>>sys.exit()
- •Using Tcl
- •And BASIC too...
- •The Raw Materials
- •Introduction
- •Data
- •Variables
- •Primitive Data Types
- •Character Strings
- •String Operators
- •String operators
- •BASIC String Variables
- •Tcl Strings
- •Integers
- •Arithmetic Operators
- •Arithmetic and Bitwise Operators
- •BASIC Integers
- •Tcl Numbers
- •Real Numbers
- •Complex or Imaginary Numbers
- •Boolean Values - True and False
- •Boolean (or Logical) Operators
- •Collections
- •Python Collections
- •List
- •List operations
- •Tcl Lists
- •Tuple
- •Dictionary or Hash
- •Other Collection Types
- •Array or Vector
- •Stack
- •Queue
- •Files
- •Dates and Times
- •Complex/User Defined
- •Accessing Complex Types
- •User Defined Operators
- •Python Specific Operators
- •More information on the Address example
- •More Sequences and Other Things
- •The joy of being IDLE
- •A quick comment
- •Sequences using variables
- •Order matters
- •A Multiplication Table
- •Looping - Or the art of repeating oneself!
- •FOR Loops
- •Here's the same loop in BASIC:
- •WHILE Loops
- •More Flexible Loops
- •Looping the loop
- •Other loops
- •Coding Style
- •Comments
- •Version history information
- •Commenting out redundant code
- •Documentation strings
- •Indentation
- •Variable Names
- •Modular Programming
- •Conversing with the user
- •>>> print raw_input("Type something: ")
- •BASIC INPUT
- •Reading input in Tcl
- •A word about stdin and stdout
- •Command Line Parameters
- •Tcl's Command line
- •And BASIC
- •Decisions, Decisions
- •The if statement
- •Boolean Expressions
- •Tcl branches
- •Case statements
- •Modular Programming
- •What's a Module?
- •Using Functions
- •BASIC: MID$(str$,n,m)
- •BASIC: ENVIRON$(str$)
- •Tcl: llength L
- •Python: pow(x,y)
- •Python: dir(m)
- •Using Modules
- •Other modules and what they contain
- •Tcl Functions
- •A Word of Caution
- •Creating our own modules
- •Python Modules
- •Modules in BASIC and Tcl
- •Handling Files and Text
- •Files - Input and Output
- •Counting Words
- •BASIC and Tcl
- •BASIC Version
- •Tcl Version
- •Handling Errors
- •The Traditional Way
- •The Exceptional Way
- •Generating Errors
- •Tcl's Error Mechanism
- •BASIC Error Handling
- •Advanced Topics
- •Recursion
- •Note: This is a fairly advanced topic and for most applications you don't need to know anything about it. Occasionally, it is so useful that it is invaluable, so I present it here for your study. Just don't panic if it doesn't make sense stright away.
- •What is it?
- •Recursing over lists
- •Object Oriented Programming
- •What is it?
- •Data and Function - together
- •Defining Classes
- •Using Classes
- •Same thing, Different thing
- •Inheritance
- •The BankAccount class
- •The InterestAccount class
- •The ChargingAccount class
- •Testing our system
- •Namespaces
- •Introduction
- •Python's approach
- •And BASIC too
- •Event Driven Programming
- •Simulating an Event Loop
- •A GUI program
- •GUI Programming with Tkinter
- •GUI principles
- •A Tour of Some Common Widgets
- •>>> F = Frame(top)
- •>>>F.pack()
- •>>>lHello = Label(F, text="Hello world")
- •>>>lHello.pack()
- •>>> lHello.configure(text="Goodbye")
- •>>> lHello['text'] = "Hello again"
- •>>> F.master.title("Hello")
- •>>> bQuit = Button(F, text="Quit", command=F.quit)
- •>>>bQuit.pack()
- •>>>top.mainloop()
- •Exploring Layout
- •Controlling Appearance using Frames and the Packer
- •Adding more widgets
- •Binding events - from widgets to code
- •A Short Message
- •The Tcl view
- •Wrapping Applications as Objects
- •An alternative - wxPython
- •Functional Programming
- •What is Functional Programming?
- •How does Python do it?
- •map(aFunction, aSequence)
- •filter(aFunction, aSequence)
- •reduce(aFunction, aSequence)
- •lambda
- •Other constructs
- •Short Circuit evaluation
- •Conclusions
- •Other resources
- •Conclusions
- •A Case Study
- •Counting lines, words and characters
- •Counting sentences instead of lines
- •Turning it into a module
- •getCharGroups()
- •getPunctuation()
- •The final grammar module
- •Classes and objects
- •Text Document
- •HTML Document
- •Adding a GUI
- •Refactoring the Document Class
- •Designing a GUI
- •References
- •Books to read
- •Python
- •BASIC
- •General Programming
- •Object Oriented Programming
- •Other books worth reading are:
- •Web sites to visit
- •Languages
- •Python
- •BASIC
- •Other languages of interest
- •Programming in General
- •Object Oriented Programming
- •Projects to try
- •Topics for further study
Frame
Layout
Child
•Text Entry
•Message boxes
The ones we won't discuss in this topic but are used elsewhere in the tutor are:
•Text box
•Radio Button
Finally, the ones not discussed at all are:
•Canvas - for drawing
•Check button - for multiple selections
•Image - for displaying BMP, GIF, JPEG and PNG images
•Listbox - for lists!
•Menu/MenuButton - for building menus
•Scale/Scrollbar - indicating position
A type of widget used to group other widgets together. Often a Frame is used to represent the complete window and further frames are embedded within it.
Controls are laid out within a Frame according to a particular form of Layout. The Layout may be specified in a number of ways, either using onscreen coordinates specified in pixels, using relative position to other components(left, top etc) or using a grid or table arrangement. A coordinate system is easy to understand but difficult to manage when a window is resized etc. Beginners are advised to use non-resizable windows if working with coordinate based layouts.
GUI applications tend to consist of a heirarchy of widgets/controls. The top level Frame comprising the application window will contain sub frames which in turn contain still more frames or controls. These controls can be visualised as a tree structure with each control having a single parent and a number of children. In fact it is normal for this structure to be strored explicitly by the widgets so that the programmer, or more commonly the GUI environment itself, can often perform some common action to a control and all its children.
A Tour of Some Common Widgets
In this section we will use the Python interactive prompt to create some simple windows and widgets. Note that because IDLE is itself a Tkinter application you cannot reliably run Tkinter applications within IDLE. You can of course create the files using IDLE as an editor but you must run them from a OS command prompt. Pythonwin users can run Tkinter applications since Pythonwin is built using windows own GUI toolkit, MFC. However even within Pythonwin there are certain unexpected behaviours with Tkinter application. As a result I will use the raw Python prompt from the Operating System.
>>> from Tkinter import *
This is the first requirement of any Tkinter program - import the names of the widgets. You could of course just import the module but it quickly gets tiring typing Tkinter in front of every component name.
83
>>> top = Tk()
This creates the top level widget in our widget heirarchy. All other widgets will be created as children of this. Notice that a new blank window has appeared complete with an empty title bar and the usual set of control buttons (iconify, maximise etc). We will now add components to this window as we build an application.
>>> dir(top)
['_tclCommands', 'children', 'master', 'tk']
The dir function shows us what names are known to the argument. You can use it on modules but in this case we are looking at the internals of the top object, an instance of the Tk class. These are the attributes of top, note, in particular, the children and parent attributes which are the links to the widget heirarchy. Note also the attribute _tclCommands, this is because, as you might recall, Tkinter is built on a Tcl toolkit called Tk.
>>> F = Frame(top)
Create a Frame widget which will in turn contain the child controls/widgets that we use. Frame specifies top as its first(and in this case only) parameter thus signifying that F will be a child widget of top.
>>>F.pack()
Notice that the Tk window has now shrunk to the size of the added Frame widget - which is currently empty so the window is now very small! The pack() method invokes a Layout Manager known as the packer which is very easy to use for simple layouts but becomes a little clumsy as the layouts get more complex. We will stick with it for now because its quite easy to use. Note that widgets will not be visible in our application until we pack them(or use another Layout manager method)
>>>lHello = Label(F, text="Hello world")
Here we create a new object lHello, an instance of the Label class, with a parent widget F and a text attribute of "Hello world". Notice that because Tkinter object constructors tend to have many parameters (each with default values) it is usual to use the named parameter technique of passing arguments to Tkinter objects. Also notice that the object is not yet visible because we haven't packed it yet.
One final point to note is the use of a naming convention: I put a lowercasel, for Label, in front of a name, Hello, which reminds me of its purpose. Like most naming conventions this is a matter of personal choice, but I find it helps.
>>>lHello.pack()
Now we can see it. Hopefully yours looks quite a lot like this:
We can specify other properties of the Label such as the font and color using parameters to the object constructor too. We can also access the corresponding properties using the configure method of Tkinter widgets, like so:
>>> lHello.configure(text="Goodbye")
84
The message changed. That was easy, wasn't it? configure is an especially good technique if you need to change multiple properties at once because they can all be passed as arguments. However if you only want to change a single property at a time, as we did above you can treat the object like a dictionary, thus:
>>> lHello['text'] = "Hello again"
which is shorter and arguably easier to understand.
Labels are pretty boring widgets, they can really only display read-only text, albeit in various colors, fonts and sizes. (In fact they can be used to display simple graphics too but I'll show you how to do that later).
Before we look at another object type there is one more thing to do and that's to set the title of the window. We do that by using a method of the top level widget top:
>>> F.master.title("Hello")
We could have used top directly but as we'll see later access through the Frame's master property is a useful technique.
>>> bQuit = Button(F, text="Quit", command=F.quit)
Here we create a new widget a button. The button has a label "Quit" and is associated with the command F.quit. Note that we pass the method name, we do not call the method by adding parentheses after it. This means we must pass a function object in Python terms, it can be a built in method provided by Tkinter, as here, or any other function that we define. The function or method must take no arguments. The quit method, like the pack method, is defined in a base class and is inherited by all Tkinter widgets.
>>>bQuit.pack()
Once again the pack method makes the button visible.
>>>top.mainloop()
We start the Tkinter event loop. Notice that the Python >>> prompt has now disappeared. That tells us that Tkinter now has control. If you press the Quit button the prompt will return, proving that our command option worked.
Note that if running this from Pythonwin or IDLE you may get a different result, if so try typing the commands so far into a Python script and running them from an OS command prompt.
In fact its probably a good time to try that anyhow, after all its how most Tkinter programs will be run in practice. Use the key commands from those we've discussed so far as shown:
from Tkinter import *
#set up the window itself top = Tk()
F = Frame(top) F.pack()
#add the widgets
lHello = Label(F, text="Hello") lHello.pack()
bQuit = Button(F, text="Quit", command=F.quit) bQuit.pack()
# set the loop running
85