The tkinter package is the standard Python interface to the Tk GUI toolkit. Both Tk and tkinter are available on Windows systems. Running python -m tkinter from the command line should open a window demonstrating a simple Tk interface, letting you know that tkinter is properly installed on your system, and also showing what version of Tcl/Tk is installed.
C:\Users\Python>python -m tkinter
User interfaces are what allows end users to interact with an application. An application
can be excellent, but without a good user interface, it becomes more difficult to use,
and less enjoyable. It is thus very important to design good user interfaces.
Designing user interface takes place at two different levels: the graphical level and
the event level. Graphical elements of a user interface are called widgets. Widgets are
basic components like buttons, scrollbars, etc. But user interfaces involve more than a
collection of widgets placed in a window. The application must be able to respond to
mouse clicks, keyboard actions or system events such as minimizing the window. For
this to happen, events must be associated to some pieces of code. This process is called
binding.
Anything that happens in a user interface is an event. We say that an event is fired whenever
the user does something – for example, clicks on a button or types a
keyboard shortcut. Some events could also be triggered by occurrences
which are not controlled by the user – for example, a background task
might complete, or a network connection might be established or lost.
Our application needs to monitor, or listen for,
all the events that we find interesting, and respond to them in some
way if they occur. To do this, we usually associate certain functions
with particular events. We call a function which performs an action in
response to an event an event handler – we bind handlers to events.
With all the competing GUI toolkits available for the Python language, what makes
Tkinter stand out of the rest? Why is it the most popular toolkit for use interface
design?
To find the answer, one must look at the advantages that it offers.
1. Layered design The layered approach used in designing Tkinter gives Tkinter
all of the advantages of the TK library. Therefore, at the time of creation, Tkinter
inherited from the benefits of a GUI toolkit that had been given time to mature.
This makes early versions of Tkinter a lot more stable and reliable than if it had
been rewritten from scratch. Moreover, the conversion from Tcl/Tk to Tkinter is
really trivial, so that Tk programmers can learn to use Tkinter very easily.
2. Accessibility Learning Tkinter is very intuitive, and therefore quick and painless.
The Tkinter implementation hides the detailed and complicated calls in simple,
intuitive methods. This is a continuation of the Python way of thinking, since the
language excels at quickly building prototypes. It is therefore expected that its
preferred GUI library be implemented using the same approach.
3. Portability Python scripts that use Tkinter do not require modifications to be
ported from one platform to the other. Tkinter is available for any platform
that Python is implemented for, namely Microsoft Windows, X Windows, and
Macintosh. This gives it a great advantage over most competing libraries, which
are often restricted to one or two platforms. Moreover, Tkinter will provide the
native look-and-feel of the specific platform it runs on.
4. Availability Tkinter is now included in any Python distribution. Therefore, no
supplementary modules are required in order to run scripts using Tkinter.
4.
Availability Tkinter is now included in any Python distribution.
Therefore, no
supplementary modules are required in order to run scripts using
Tkinter. Tkinter has many advantages that make it the primary choice for
UI design. However,
it has a drawback which originates directly from its implementation: it
has a significant
overhead due to its layered implementation. While this could constitute a
problem with
older, slower machines, most modern computers are fast enough so as to
cope with the
extra processing in a reasonable amount of time. When speed is critical,
however,
proper care must be taken so as to write code that is as efficient as
possible.
Even
if the overhead tends to become less relevant with time, there is still
a disadvantage to this layered implementation that is not going to fade
away: the source
code for the Tkinter library is only a shell that provides Tk’s
functionality to Python
programs. Therefore, in order to understand what the Tkinter source code
does, programmers need to understand the source code of the Tk library,
which is in turn written
in C. While certainly not impossible, this requires more work from
programmers and
can be quite time consuming.
- Import the Tkinter module.
- Create the GUI application main window.
- Add one or more of the above-mentioned widgets to the GUI application.
- Enter the main event loop to take action against each event triggered by the user.
Let's look at a very simple program which uses tkinter:
import tkinter
top = tkinter.Tk()
top.title('First example')
top.mainloop()
top = tkinter.Tk()
top.title('First example')
top.mainloop()
When we run this program we get this window as output:
Let’s analyze the code line by line. import tkinter This line imports the whole Tkinter library. It must present in every Tkinter program.
top = tkinter.Tk()
This line creates a complete window, called the Tk root widget saved in the variable top. There should be only
one root widget per application, and it must be created before all other widgets. This
does not mean that tkinter applications cannot have multiple windows at the same
time.
top.title('First example')
This line invokes a method of the Tk root widget instance to set its title to ’First example’. For the purposes of this example, this is the simplest way of displaying
text in the window.
top.mainloop( )
The call to mainloop makes the application enter its event loop, i.e it makes it able to
respond to user events, such as mouse events and keyboard events.
Now let us make another program which uses new widgets (visual
components) to display some text and exit the application. See the code below:
from tkinter import *
def quit():
import sys;sys.exit
root = Tk()
lbl = Label(root, text="Press the button below to exit")
lbl.pack()
btn = Button(root, text="Quit", command=quit)
btn.pack()
root.mainloop( )
import sys;sys.exit
root = Tk()
lbl = Label(root, text="Press the button below to exit")
lbl.pack()
btn = Button(root, text="Quit", command=quit)
btn.pack()
root.mainloop( )
This example creates new widgets to
put on the root window. Also, it responds to a specific user event (a click on the “Quit”
button) by exiting the program.
def quit():
import sys; sys.exit()
These two lines are not Tkinter-specific. They simply create a function which terminates the application when invoked.
lbl = Label(root, text="Press the button below to exit")
This line creates a new instance of the Label class. The first argument of any widget
constructor is always to master widget, in other words to widget which will hold the
new widget. In this case, the Tk root widget is specified as master, so that the new
widgets will appear in the window we have created. The following arguments are
usually passed by keyword, and represent various options of the widget. The available
options depend on the widget type.
In
this specific case, the only option that is needed is the text to be displayed by the widget.
Widgets have their default value for all of the available options, so that they do not need
to be specified unless the default value does not fit the needs of the programmer.
lbl.pack()
Even though a instance of the Label class was created by the previous line, it does not
yet appear on the root window. A geometry manager needs to be used in order to place
the new widget in its master widget. In this case, the packer does this in a very simple
way. Its default behaviour is to pack every new widget in a column, starting at the top
of the master.
btn = Button(root, text="Quit", command=quit)
btn.pack()
These two lines again create a new widget, but this time it is an instance of the Button
class. This button will display the text “Quit”, and the quit function will be invoked
when it is clicked. This packer is once again responsible for placing this widget on the
master window.
root.mainloop()
Once all widgets have been created, root.mainloop() is called in order to enter the
event loop and allow the widgets to receive and react to user events (in this case a click
on the button).
We can restructure the above program as shown below to make it into a class.
This is usually how more complex Tkinter programs are implemented, since it is a
much cleaner way to organize things.
class MyFirstGUI:
def __init__(self,master):
self.lbl = Label(master, text="Press the button below to exit")
self.lbl.pack()
self.btn = Button(master, text="Quit", command=self.quit)
self.btn.pack()
def quit(self):
import sys; sys.exit()
root = Tk( )
myFGUI = MyFirstGUI(root)
root.mainloop()
def __init__(self,master):
self.lbl = Label(master, text="Press the button below to exit")
self.lbl.pack()
self.btn = Button(master, text="Quit", command=self.quit)
self.btn.pack()
def quit(self):
import sys; sys.exit()
root = Tk( )
myFGUI = MyFirstGUI(root)
root.mainloop()
When we run this program we get the following output:
This example defines a new class: MyFirstGUI. This class only has a constructor
and a quit method. The quit method is almost identical to the quit function from the previous example, except that it must take a parameter, self, to receive a reference to the
class instance when invoked.
When we click quit button the window closes and the program exits. We can further add functionalities to our program, for example add one more button 'Greet" which when clicked prints 'Howdy!' on the screen. See the code below:
from tkinter import *
class MyFirstGUI:
def __init__(self, master):
self.master = master
self.lbl = Label(master, text="Press the button below to exit")
self.lbl.pack()
self.btn = Button(master, text="Greet",command=self.greet)
self.btn.pack()
self.btn = Button(master, text="Quit",command=self.quit)
self.btn.pack()
def greet(self):
print("Howdy!")
def quit(self):
import sys; sys.exit()
root = Tk( )
myFGUI = MyFirstGUI(root)
root.mainloop()
class MyFirstGUI:
def __init__(self, master):
self.master = master
self.lbl = Label(master, text="Press the button below to exit")
self.lbl.pack()
self.btn = Button(master, text="Greet",command=self.greet)
self.btn.pack()
self.btn = Button(master, text="Quit",command=self.quit)
self.btn.pack()
def greet(self):
print("Howdy!")
def quit(self):
import sys; sys.exit()
root = Tk( )
myFGUI = MyFirstGUI(root)
root.mainloop()
When we run the program we get the following window with a title, a text label and two buttons – one which prints a message in the console, and one which closes the window. The window should have all the normal properties of any other window you encounter in your window manager – you are probably able to drag it around by the titlebar, resize it by dragging the frame, and maximise, minimise or close it using buttons on the titlebar.
We are using three widgets:
Tk
is the class which we use to create the root window – the main window of our application. Our application should only have one root, but it is possible for us to create other windows which are separate from the main window.Button
and Label
should be self-explanatory. Each of them has a parent widget, which we pass in as the first parameter to the constructor – we have put the label and both buttons inside the main window, so they are the main window’s children in the tree. We use the pack
method on each widget to position it inside its parent – we will learn about different kinds of layout later.
All three of these widgets can display text (we could also make them display images). The label is a static element – it doesn’t do anything by default; it just displays something. Buttons, however, are designed to cause something to happen when they are clicked. We have used the
command
keyword parameter when constructing each button to specify the function which should handle each button’s click events – both of these functions are object methods.
We didn’t have to write any code to make the buttons fire click events or to bind the methods to them explicitly. That functionality is already built into the button objects – we only had to provide the handlers. We also didn’t have to write our own function for closing the window, because there is already one defined as a method on the window object. We did, however, write our own method for printing a message to the console.
There are many ways in which we could organise our application class. In this example, our class doesn’t inherit from any
tkinter
objects – we use composition to associate our tree of widgets with our class. We could also use inheritance to extend one of the widgets in the tree with our custom functions.root.mainloop()
is a method on the main window which we execute when we want to run our application. This method will loop forever, waiting for events from the user, until the user exits the program – either by closing the window, or by terminating the program with a keyboard interrupt in the console.
Here I am ending today's discussion. Till we meet next keep practicing and learning Python as Python is easy to learn!
0 comments:
Post a Comment