Examples are the main way that I learned about Tkinter and how to write code for building GUI’s . Unfortunately, it is hard to find examples. Grayson’s book has been an immense help over the years and more recently the pyttk-samples distributed by Guilherme Polo have helped greatly. The official Tcl documentation is pretty much limited to man pages which are of minor assistance in getting started with Tkinter. The tutorial on the Tcl Developers site only recently included Python code. Much experimentation was required before I was able to see a paned window on my screen or a scrolled directory. There are several interesting examples in the examples subdirectory.
Most of the examples have been reworked for version 4.2 to reflect the rework scheme have a GUI module and a support module for each GUI. So one may experiment with the examples changing sizes, colors, fonts, etc. in the GUI modules and they may still work if he does not regenerate support modules. At least, one can see some of the possibilities. Of course, I have created some of them like menu in poor taste just to illustrate some of the possibilities.
If you try running the examples by executing PAGE on the Tcl files be aware that generating and saving support files will replace the included support files which will become backup versions and the functioning of the applications will be lost.
This example contains a scrolled treeview widget that displays ones UNIX directory tree. The source for this example is in examples/directory-tree.py It is a rework of Polo’s example to include folder icons which open and close. Polo’s example is Based on bitwalk’s directory browser.
In the past I have used a number of regular expressions in Python and used to great advantage Visual Regexp in composing and testing those regular expressions and thought that rewriting the program in Python would be interesting because
The main portion of the GUI is a three pane window for entering the regular expression and sample in the first two and the third pane presents match results based on the selection of buttons at the bottom.
Some of the features of PAGE illustrated in this useful program are:
Briefly, Vrex works as follows:
One enters the regular expression under test into the top text box, and the sample which is the subject of the regular expression match into the middle text box. One may use the File menu to load files into the text boxes, one may directly type entries or use the normal cut and paste facilities of the operating system. The user can also save the regular expression and sample using the File menu.
The regular expression should be colorized showing the portions to be extracted in different colors and as well as the matching portion of the sample.
If you then Select Match, that matching portion of the sample will be shown in the Match text box. Select 1, and the portion matching the sub expression will be shown, etc..
You can also load a file into the sample window and thus run the regular expression against many strings.
This example shows the usage of the progress bar widget but is included mainly for illustrating an application with two top level windows. It shows how the main window is able to interact with variables and procedures in the imported module which actually displays the progress bar.
Two versions of this example are included, the first in the examples/progress_bar is the version that I wrote before implementing the rework scheme and the second in examples/rework_progress_bar is how I changed the first to conform with the new scheme. Important features illustrated include the creation and destruction of the secondary top level window and the fact that the main GUI support code requires access to Tkinter variables defined and manipulated in the support module of the other, progress bar, window.
This really isn’t much of an example doing nothing but does showing nesting of a paned window inside of a paned window and a notebook widget nested inside of a paned window. By the way, one can enlarge the top level window and copy and paste the whole paned window to a new location.
This is just a top level window with each of the standard Tk widgets that I support. It just shows that I can generate working Python code for each. The lowercase ‘s’ emphasizes that it doesn’t do much.
As above for the themed widgets.
Paul Krieger donated a canvas example which can be found in the <page_dir>/examples/canvas directory. I am very thankful since I have no facility with the canvas widget.
See the WCPE directory in the examples directory. This is a program that displays the program of WCPE which is one of my favorite classical music stations. In this example all of the functional code is located in WCPE_support.py and the GUI is defined in WCPE.py which is the main module. I found it very tricky to deal with time zones and did not want to loose any of that code and have to redo it or to deal with diff’s; at the same time, I was constantly tweaking the GUI. I generated the import module once and proceeded fill out the “init” function and the callback functions in WCPE_support.py while tweaking the GUI, i.e., changing its location, color, the size of the display fields, and change of some display fields from entry boxes to labels.
This example requires the Python time zone package pytz which is available from Python Package Index.
This example utilizes:
In addition I fuss around with reading and parsing web pages and time zone calculations.
This is a somewhat kooky example located in examples/clone, where main.py creates a GUI which presents a button “Make Two” which cause the creation of two instances of the “called” GUI but with differing characteristics of location and background colors. The called GUI is then able to create incidences of clones with different locations and background colors.
It is also an example of passing a user parameter to the creation module which is then passed to the “init” function in the support module where the color and location are manipulated.
There may be a problem executing this example on Windows if fonts selected in the tcl are not available on the Windows machine. In that case the font will default to TkDefaultFont. Courier New is available on both my Linux system and my XP box.
This example show two way of defining the textvaribles associated with the label widgets in the called GUI. One way is to define (automatically) as a tk variable in the support module. The second is to define, again automatically, as a variable in the GUI module by defining it as “self.<variable>” in the attribute editor. PAGE supports both, but I now see no advantage to using the second way, and I think it is a bit more confusing.
Small example of building a calendar display using the new rework scheme. It is located in examples/calendar subfolder.
Another small example which displays the output of lscpu on a Linux system. This does not execute properly on Windows machine because it utilizes a Linux command.
This example, in <page-dir>/examples/custom/canvas, shows how I used a custom widget called ScrolledFrame which I borrowed from the web. This widget is used to display 100 buttons on a scrolled canvas.
When the user open PAGE with canvas.tcl, he sees
which shows the toplevel window filled with a custom widget. Since the structure of the widget is unknown to PAGE, it cannot be shown or manipulated other than sizing or placement.
When the support module custom_support.py is completed with the Python Tkinter implementation, execution yields
The main module is canvas.py and the magic is contained in canvas_support.py, which contains the Python/Tkinter code to implement the class
In canvas.py the custom widget is referred to in the line:
self.Custom1 = canvas_support.Custom(top)
In canvas_support.py the line of code:
Custom = Frame
is generated by PAGE causing the Custom widget to implemented as a Frame widget. In other words, the name Custom refers to the Class frame. This allows PAGE to display the Custom widget as a Frame widget with the annotation of “Custom widget” and the execution of the generated Python code to display the Custom widget as a Frame prior to including the tkinter implementation in the support module.
The user-added implementation of the ScrolledFrame class at the bottom of canvas_support.py begins as follows:
import Tkinter # I found this code on the web at # http://tkinter.unpythonic.net/wiki/ScrolledFrame and thought it would # implement a canvas widget that I could use with PAGE, but I don't understand # it well enough to put it in my supported widgets. GM_KEYS = set( vars(Tkinter.Place).keys() + vars(Tkinter.Pack).keys() + vars(Tkinter.Grid).keys() ) class ScrolledFrame(object): _managed = False # XXX These could be options x_incr = 10 y_incr = 10 def __init__(self, master=None, **kw): self.width = kw.pop('width', 200) self.height = kw.pop('height', 200) self._canvas = Tkinter.Canvas(master, **kw) self.master = self._canvas.master self._hsb = Tkinter.Scrollbar(orient='horizontal', command=self._canvas.xview) self._vsb = Tkinter.Scrollbar(orient='vertical', command=self._canvas.yview) self._canvas.configure( xscrollcommand=self._hsb.set, ... Custom = ScrolledFrame
That last line of code in canvas_support.py causes the name “Custom” to refer to the class ScrolledFrame. It overrides the previous reference to the class Frame. It is the incantation magic that cause the Custom1 widget in canvas.py to be implemented as an instance of the ScrolledFrame class.
This is a second example using the ScrolledFrame widget.
For testing of PAGE, I recoded a photo library program which I wrote several years ago using PAGE to generate the seven GUI’s required for the program. For this example, I have stripped it down to just one GUI which provides multiple display of just one image.
The demo generates the following window:
It displays repeated copies of the thumbnail image of a particular photograph as images on a Button widget. If one selects an image button with Button-1, a message appears containing the index of the button. If one selects a button with Button-3, a popup menu appears. The Zoom cascade menu in both the toplevel window and the popup menu allows one to change the size of the images displayed. There is only one image included in the example and it is displayed 30 times.
When the toplevel window is filled, the program determines, the maximum number of images that will fit horizontally and put that number in each row. If the image is too big to fit, one image per row is displayed but spills over the edge.
I have included the Busy Cursor code which is located in the shared module. However, the refresh is so fast, one can hardly see the different cursor.