You are on page 1of 34

Module 5: Object-Oriented Programming and Graphical User interface

What do we learn in this chapter?


In this chapter, we’ll learn about Collection of New Information Object-Oriented Programming :
Understanding a Problem Domain, Function “Isinstance,” Class Object, and Class Book, Writing
a Method in Class Book, Plugging into Python Syntax: More Special Methods.

Creating Graphical User interface: Building a Basic GUI, Models, Views, and Controllers,
Customizing the Visual Style Introducing few more Widgets, Object-Oriented GUIs, Keeping the
Concepts from Being a GUI Mess.

5.1 Introduction to OOP using Python

 In all the programs we wrote till now, we have designed our program around functions i.e.
blocks of statements which manipulate data. This is called the procedure-oriented way of
programming.
 There is another way of organizing your program which is to combine data and
functionality and wrap it inside something called an object. This is called the object
oriented programming paradigm.

 Object-oriented programming (OOP) is a method of structuring a program by bundling


related properties and behaviors into individual objects. In this tutorial, you’ll learn the
basics of object-oriented programming in Python.
 Conceptually, objects are like the components of a system. Think of a program as a
factory assembly line of sorts. At each step of the assembly line a system component
processes some material, ultimately transforming raw material into a finished product.
 An object contains data, like the raw or preprocessed materials at each step on an
assembly line, and behavior, like the action each assembly line component performs.

5.1.1 Understanding a Problem Domain


Object-oriented programming revolves around defining and using new types. A class in Python
represents a type. Object-oriented programming involves at least these phases:

Prepared By: Dr. Rama Satish K V, Asst Professor, RNSIT, Bengaluru


Phase 1 Understanding the problem domain.

Phase 2 Figuring out what type(s) you might want.

Phase 3 Figuring out what features you want your type to have.

Phase 4 Writing a class that represents this type.

Phase 5 Testing your code.


1. Understanding the problem domain. This step is crucial: we need to know what our customer
wants before we can write a program that does what the customer wants.

2. Figuring out what type(s) we might want. A good starting point is to read the description of the
problem domain and look for the main nouns and noun phrases.

3. Figuring out what features we want our type to have. Here we should write some code that uses
the type we’re thinking about, much like we did with the Book code at the beginning of this chapter.
This is a lot like the Examples step in the function design recipe, where we decide what the code
that we’re about to write should do.

4. Writing a class that represents this type. We now need to tell Python about your type. To do this,
we will write a class, including a set of methods inside that class.

5. Testing our code. Our methods will have been tested separately as we followed the function
design recipe, but it’s important to think about how the various methods will interact.

5.1.2 What Is Object-Oriented Programming in Python?

 Object-oriented programming is a programming paradigm that provides a means of


structuring programs so that properties and behaviors are bundled into individual objects.
 For instance, an object could represent a person with properties like a name, age, and
address and behaviors such as walking, talking, breathing, and running. Or it could
represent an email with properties like a recipient list, subject, and body and behaviors like
adding attachments and sending.
 Put another way, object-oriented programming is an approach for modeling concrete, real-
world things, like cars, as well as relations between things, like companies and employees,

Prepared By: Dr. Rama Satish K V, Asst Professor, RNSIT, Bengaluru


students and teachers, and so on. OOP models real-world entities as software objects that
have some data associated with them and can perform certain functions.
 Another common programming paradigm is procedural programming, which structures
a program like a recipe in that it provides a set of steps, in the form of functions and code
blocks, that flow sequentially in order to complete a task.
 The key takeaway is that objects are at the center of object-oriented programming in
Python, not only representing the data, as in procedural programming, but in the overall
structure of the program as well.
 Classes are used to create user-defined data structures. Classes define functions called
methods, which identify the behaviors and actions that an object created from the class can
perform with its data.
 We will create a Dog class that stores some information about the characteristics and
behaviors that an individual dog can have.
 A class is a blueprint for how something should be defined. It doesn’t actually contain any
data. The Dog class specifies that a name and an age are necessary for defining a dog, but
it doesn’t contain the name or age of any specific dog.
 While the class is the blueprint, an instance is an object that is built from a class and contains
real data. An instance of the Dog class is not a blueprint anymore. It’s an actual dog with a
name, like Miles, who’s four years old.
 Put another way, a class is like a form or questionnaire. An instance is like a form that has
been filled out with information. Just like many people can fill out the same form with their
own unique information, many instances can be created from a single class.
 All class definitions start with the class keyword, which is followed by the name of the
class and a colon. Any code that is indented below the class definition is considered part of
the class’s body.

class Dog:
pass

 The body of the Dog class consists of a single statement: the pass keyword. pass is
often used as a placeholder indicating where code will eventually go. It allows
you to run this code without Python throwing an error.
 Creating a new object from a class is called instantiating an object. You can
instantiate a new Dog object by typing the name of the class, followed by opening
and closing parentheses:

Prepared By: Dr. Rama Satish K V, Asst Professor, RNSIT, Bengaluru


>>> Dog()
<__main__.Dog object at 0x106702d30>

We now have a new Dog object at 0x106702d30. This funny-looking string of letters and
numbers is a memory address that indicates where the Dog object is stored in your computer’s
memory. Note that the address you see on your screen will be different.

5.1.3 Instance variable and class variables


• Objects can store data using ordinary variables that belong to the object.
• Variables that belong to an object or class are referred to as fields.
• Objects can also have functionality by using functions that belong to a class. Such functions
are called methods of the class.

• Fields are of two types - they can belong to each instance/object of the class or they can
belong to the class itself. They are called instance variables and class
variables respectively.

• A class is created using the class keyword. The fields and methods of the class are listed in
an indented block.

OOP Terminology
 Class − A user-defined prototype for an object that defines a set of attributes that
characterize any object of the class. The attributes are data members (class variables and
instance variables) and methods, accessed via dot notation.

 Class variable − A variable that is shared by all instances of a class. Class variables are
defined within a class but outside any of the class's methods. Class variables are not used
as frequently as instance variables are.

Prepared By: Dr. Rama Satish K V, Asst Professor, RNSIT, Bengaluru


 Data member − A class variable or instance variable that holds data associated with a class
and its objects.

 Function overloading − The assignment of more than one behavior to a particular function.
The operation performed varies by the types of objects or arguments involved.

 Instance variable − A variable that is defined inside a method and belongs only to the
current instance of a class.

 Inheritance − The transfer of the characteristics of a class to other classes that are derived
from it.

 Instance − An individual object of a certain class. An object obj that belongs to a class
Circle, for example, is an instance of the class Circle.

 Instantiation − The creation of an instance of a class.


 Method − A special kind of function that is defined in a class definition.

 Object − A unique instance of a data structure that's defined by its class. An object
comprises both data members (class variables and instance variables) and methods.

 Operator overloading −The assignment of more than one function to a particular operator.

 The class has a documentation string, which can be accessed via ClassName.__doc__.
 The class_suite consists of all the component statements defining class members, data
attributes and functions.

class Employee:
'Common base class for all employees'
empCount = 0

def __init__(self, name, salary):


self.name = name
self.salary = salary
Employee.empCount += 1

def displayCount(self):
print "Total Employee %d" % Employee.empCount

def displayEmployee(self):
print "Name : ", self.name, ", Salary: ", self.salary

Prepared By: Dr. Rama Satish K V, Asst Professor, RNSIT, Bengaluru


 The variable empCount is a class variable whose value is shared among all instances of a
this class. This can be accessed as Employee.empCount from inside the class or outside
the class.

 The first method __init__() is a special method, which is called class constructor or
initialization method that Python calls when you create a new instance of this class.

 You declare other class methods like normal functions with the exception that the first
argument to each method is self. Python adds the self argument to the list for you;
you do not need to include it when you call the methods.

The self and __init__


• Class methods have only one specific difference from ordinary functions - they must have
an extra first name that has to be added to the beginning of the parameter list.

• when you call the method, Python will provide it. This particular variable refers to the
object itself, and by convention, it is given the name self.

• This also means that if you have a method which takes no arguments, then you still have
to have one argument - the self.

• There are many method names which have special significance in Python classes. We will
see the significance of the __init__ method now.

• The __init__ method is run as soon as an object of a class is instantiated. The method is
useful to do any initialization you want to do with your object. Notice the double
underscores both at the beginning and at the end of the name.

Creating Instance Objects


• To create instances of a class, you call the class using class name and pass in whatever
arguments its __init__ method accepts.

#This would create first object of Employee class


emp1 = Employee("Zara", 2000)

#This would create second object of Employee class


emp2 = Employee("Manni", 5000)

Accessing Attributes
• You access the object's attributes using the dot operator with object. Class variable would
be accessed using class name as follows −

Prepared By: Dr. Rama Satish K V, Asst Professor, RNSIT, Bengaluru


emp1.displayEmployee()
emp2.displayEmployee()
print("Total Employee %d" % Employee.empCount)

Example:

class Employee:
'Common base class for all employees'
empCount = 0

def __init__(self, name, salary):


self.name = name
self.salary = salary
Employee.empCount += 1

def displayCount(self):
print("Total Employee %d" % Employee.empCount)

def displayEmployee(self):
print("Name : ", self.name, ", Salary: ", self.salary)

emp1 = Employee("Zara", 2000)


emp2 = Employee("Manni", 5000)

emp1.displayEmployee()
emp2.displayEmployee()
print ("Total Employee %d" % Employee.empCount)

When the above code is executed, it produces the following result −


Name : Zara ,Salary: 2000
Name : Manni ,Salary: 5000
Total Employee 2

Function “Isinstance,”
• Function isinstance reports whether an object is an instance of a class—that is, whether
an object has a particular type:
>>> isinstance('abc', str)
True
>>> isinstance(55.2, str)
False
• 'abc' is an instance of str, but 55.2 is not.
Note: Python has a class called object. Every other class is based on it.
>>> isinstance(55.2, object)
True
>>> isinstance('abc', object)
True

Prepared By: Dr. Rama Satish K V, Asst Professor, RNSIT, Bengaluru


Creating a class and checking its type
>>> class Book:
... """Information about a book."""
...
>>> type(str)
<class 'type'>
>>> type(Book)
<class 'type'>

Memory representation of Classes and Objects


>>> ruby_book = Book()
>>> ruby_book.title = 'Programming Ruby'
>>> ruby_book.authors = ['Thomas','Fowler','Hunt']

General form of defining a class


• The first line tells us that we asked for help on class Book. After that is the header
for class Book; the (builtins.object) part tells us that Book is a subclass of class
object.
• The next line shows the Book docstring. Last is a section called “data descriptors,”
which are special pieces of information that Python keeps with every user-defined
class that it uses for its own purposes.

Prepared By: Dr. Rama Satish K V, Asst Professor, RNSIT, Bengaluru


Writing a Method in Class Book

Writing __init__() with arguments


class Book:
def __init__(self, title, authors, publisher,
isbn, price):
self.title = title
self.authors = authors[:]
self.publisher = publisher
self.ISBN = isbn
self.price = price
def num_authors(self):
return len(self.authors)

>>> import book


>>> python_book = book.Book(
... 'Practical Programming',

Prepared By: Dr. Rama Satish K V, Asst Professor, RNSIT, Bengaluru


... ['Campbell', 'Gries', 'Montojo'],
... 'Pragmatic Bookshelf',
... '978-1-93778-545-1', >>> python_book.title
'Practical Programming'
>>> python_book.authors
['Campbell', 'Gries', 'Montojo']
>>> python_book.publisher
'Pragmatic Bookshelf'
>>> python_book.ISBN
'978-1-93778-545-1'
>>> python_book.price
25.0

Special Methods
• Consider
>>> print(python_book)
<book.Book object at 0x59f410>
• This is the default behavior for converting objects to strings: it just shows us where the object is
in memory. This is the behavior defined in class object’s method __str__, which our Book class
has inherited.
• If we want to present a more useful string, we need to explore two more special methods,
__str__ and __repr__.
• __str__ is called when an informal, human-readable version of an object is needed, and is called
when unambiguous, but possibly less-readable, outp__repr__ ut is desired.

Prepared By: Dr. Rama Satish K V, Asst Professor, RNSIT, Bengaluru


• Example:
>>> class Point:
... def __init__(self, x, y):
... self.x, self.y = x, y
... def __repr__(self):
... return 'Point(x=%s, y=%s)' % (self.x, self.y)
>>> p = Point(1, 2)
>>> p
Point(x=1, y=2)

• In particular, __str__ is called when print is used, and it is also called by function str and
by string method format.
• Let’s define method Book.__str__ to provide useful output; this method goes inside class
Book,

def __str__(self):
return """Title: {0} Authors: {1} Publisher: {2} ISBN: {3} Price:
Rs{4}""".format(self.title, ', '.join(self.authors),
self.publisher, self.ISBN, self.price)
Complete Example:
class Book:
def __init__(self, title, authors, publisher,
isbn, price):
self.title = title
self.authors = authors[:]
self.publisher = publisher
self.ISBN = isbn
self.price = price
def num_authors(self):
return len(self.authors)
def __str__(self):
return """Title: {0} Authors: {1} Publisher: {2}
ISBN: {3} Price: Rs{4}""".format(self.title,
','.join(self.authors), self.publisher, self.ISBN,
self.price)
Printing a Book now gives more useful information:
>>> python_book = Book(
... 'Practical Programming',
... ['Campbell', 'Gries', 'Montojo'],
... 'Pragmatic Bookshelf',
... '978-1-93778-545-1',
... 25.0)

Prepared By: Dr. Rama Satish K V, Asst Professor, RNSIT, Bengaluru


>>> print(python_book)
Title: Practical Programming
Authors: Campbell, Gries, Montojo
Publisher: Pragmatic Bookshelf
ISBN: 978-1-93778-545-1
Price: $25.0
__repr__ should return a printable representation of the object, most likely one of the ways possible to
create this object. See official documentation here. __repr__ is more for developers while __str__ is
for end users.

Example:
class Book:
def __init__(self, title, authors, publisher, isbn, price):
self.title = title
self.authors = authors[:]
self.publisher = publisher
self.ISBN = isbn
self.price = price
def num_authors(self):
return len(self.authors)
def __repr__(self):
return '''Title=%s
Authors = %s
Publisher = %s
ISbN = %s
Price=%f''' % (self.title,self.authors, self.publisher,
self.ISBN, self.price)
python_book1 = Book("Programming with Python",
['Satish', 'Suma', 'Roopa', 'Rajani'],
'GaneshXerox',
'1-244-211',
500.00)
print(python_book1)

Python Inheritance
Inheritance allows us to define a class that inherits all the methods and properties from another
class.

Prepared By: Dr. Rama Satish K V, Asst Professor, RNSIT, Bengaluru


Inheritance is the capability of one class to derive or inherit the properties from another class.
The benefits of inheritance are:

 It represents real-world relationships well.


 It provides reusability of a code. We don’t have to write the same code again and again.
Also, it allows us to add more features to a class without modifying it.
 It is transitive in nature, which means that if class B inherits from another class A, then all
the subclasses of B would automatically inherit from class A.

Parent class is the class being inherited from, also called base class.

Child class is the class that inherits from another class, also called derived class.

Create a Parent Class


Any class can be a parent class, so the syntax is the same as creating any other class:
Example Create a class named Person, with firstname and lastname properties, and
a printname method:

class Person:
def __init__(self, fname, lname):
self.firstname = fname
self.lastname = lname

def printname(self):
print(self.firstname, self.lastname)

#Use the Person class to create an object, and then execute the
printname method:

x = Person("Rama", "Satish")
x.printname()

Create a Child Class


To create a class that inherits the functionality from another class, send the parent class as a
parameter when creating the child class:

Example Create a class named Student, which will inherit the properties and methods from the
Person class:

Prepared By: Dr. Rama Satish K V, Asst Professor, RNSIT, Bengaluru


class Person:
def __init__(self, fname, lname):
self.firstname = fname
self.lastname = lname

def display(self):
print(self.firstname, self.lastname)

class Student(Person):
pass

x = Student("Sairam", "Srivatsa")
x.display()

Add the __init__() Function


We want to add the __init__() function to the child class (instead of the pass keyword).

Note: The __init__() function is called automatically every time the class is being used to
create a new object.

# Python code to demonstrate how parent constructors


# are called.

# parent class
class Person( object ):

# __init__ is known as the constructor


def __init__(self, name, idnumber):
self.name = name
self.idnumber = idnumber

# child class
class Employee( Person ):
def __init__(self, name, idnumber, salary, post):
self.salary = salary
self.post = post

# invoking the __init__ of the parent class


Person.__init__(self, name, idnumber)

def display(self):
print(self.name, self.idnumber, self.salary, self.post)

# creation of an object variable or an instance


a = Employee('Rahul', 886012, 200000, "Intern")

# calling a function of the class Person using its instance


a.display()

Prepared By: Dr. Rama Satish K V, Asst Professor, RNSIT, Bengaluru


Different forms of Inheritance:

1. Single inheritance: When a child class inherits from only one parent class, it is called
single inheritance. We saw an example above.
2. Multiple inheritance: When a child class inherits from multiple parent classes, it is called
multiple inheritance. Unlike Java and like C++, Python supports multiple inheritance. We
specify all parent classes as a comma-separated list in the bracket.

# Python example to show the working of multiple


# inheritance
class Base1(object):
def __init__(self):
self.str1 = "RNSIT"
print("Base1")

class Base2(object):
def __init__(self):
self.str2 = "MCA"
print("Base2")

class Derived(Base1, Base2):


def __init__(self):

# Calling constructors of Base1


# and Base2 classes
Base1.__init__(self)
Base2.__init__(self)
print("Derived : Software Professional")

def printStrs(self):
print(self.str1, self.str2)

ob = Derived()
ob.printStrs()

Prepared By: Dr. Rama Satish K V, Asst Professor, RNSIT, Bengaluru


#Python program to demonstrate multilevel inheritance
class Base(object):

# Constructor
def __init__(self, name):
self.name = name

# Inherited or Sub class (Note Person in bracket)


class Child(Base):

# Constructor
def __init__(self, name, age):
Base.__init__(self, name)
self.age = age

# Inherited or Sub class (Note Person in bracket)


class GrandChild(Child):

# Constructor
def __init__(self, name, age, address):
Child.__init__(self, name, age)
self.address = address

# To get address
def display(self):
return self.name, self.age, self.address

# Driver code
g = GrandChild("RNSIT", 20, "Bengaluru")
print(g.display())

Magic Methods

Magic methods in Python are the special methods which add "magic" to your class. Magic
methods are not meant to be invoked directly by you, but the invocation happens internally from
the class on a certain action. For example, when you add two numbers using the + operator,
internally, the __add__() method will be called.

Important Magic Methods

The following tables list important magic methods in Python 3.

Operator Magic Methods Description

__add__(self, other) To get called on add operation using + operator

__sub__(self, other) To get called on subtraction operation using - operator.

Prepared By: Dr. Rama Satish K V, Asst Professor, RNSIT, Bengaluru


Operator Magic Methods Description

__mul__(self, other) To get called on multiplication operation using * operator.

__floordiv__(self, other) To get called on floor division operation using // operator.

__truediv__(self, other) To get called on division operation using / operator.

__mod__(self, other) To get called on modulo operation using % operator.

__pow__(self, other[, modulo]) To get called on calculating the power using ** operator.

__lt__(self, other) To get called on comparison using < operator.

__le__(self, other) To get called on comparison using <= operator.

__eq__(self, other) To get called on comparison using == operator.

__ne__(self, other) To get called on comparison using != operator.

__ge__(self, other) To get called on comparison using >= operator.

__add__() method

In following example, a class named distance is defined with two instance attributes - ft and
inch. The addition of these two distance objects is desired to be performed using the overloading
+ operator. To achieve this, the magic method __add__() is overridden, which performs the
addition of the ft and inch attributes of the two objects. The __str__() method returns the object's
string representation.
Example:

class distance:
def __init__(self, x=None,y=None):
self.ft=x
self.inch=y
def __add__(self,x):
temp=distance()
temp.ft=self.ft+x.ft
temp.inch=self.inch+x.inch
if temp.inch>=12:
temp.ft+=1
temp.inch-=12
return temp
def __str__(self):
return 'ft:'+str(self.ft)+' in: '+str(self.inch)

Run the above Python script to verify the overloaded operation of the + operator.

Prepared By: Dr. Rama Satish K V, Asst Professor, RNSIT, Bengaluru


>>> d1=distance(3,10)
>>> d2=distance(4,4)
>>> print("d1= {} d2={}".format(d1, d2))
d1= ft:3 in: 10 d2=ft:4 in: 4
>>>d3=d1+d2
>>>print(d3)
ft:8 in: 2

Prepared By: Dr. Rama Satish K V, Asst Professor, RNSIT, Bengaluru


Creating Graphical User Interfaces
Most of the programs in previous chapters are not interactive. Once launched, they run to
completion without giving us a chance to steer them or provide new input. The few that do
communicate with us do so through the kind of text-only command-line user interface, or CLUI,
that would have already been considered old-fashioned in the early 1980s.

As you already know, most modern programs interact with users via a graphical user interface,
or GUI, which is made up of windows, menus, buttons, and so on. In this chapter, we will show
you how to build simple GUIs using a Python module called tkinter. Along the way, we will
introduce a different way of structuring programs called event-driven programming. A
traditionally structured program usually has control over what happens when, but an event-
driven program must be able to respond to input at unpredictable moments. tkinter is one of
several toolkits you can use to build GUIs in Python. It is the only one that comes with a standard
Python installation.

5.2 Using Module Tkinter

Every tkinter program consists of these things:


• Windows, buttons, scrollbars, text areas, and other widgets—anything that you can see on the
computer screen (Generally, the term widget means any useful object; in programming, it is short
for “window gadget.”)
• Modules, functions, and classes that manage the data that is being shown in the GUI—you are
familiar with these; they are the tools you’ve seen so far in this book.
• An event manager that listens for events such as mouse clicks and keystrokes and reacts to
these events by calling event handler functions.
Here is a small but complete tkinter program:
import tkinter
window = tkinter.Tk()
window.mainloop()
Tk is a class that represents the root window of a tkinter GUI. This
root window’s mainloop method handles all the events for the GUI, so
it’s important to create
only one instance of Tk.
Here is the resulting GUI:

Prepared By: Dr. Rama Satish K V, Asst Professor, RNSIT, Bengaluru


The root window is initially empty; you’ll see in the next section how to add widgets to it. If the
window on the screen is closed, the window object is destroyed (though we can create a new root
window by calling Tk() again). All of the applications we will create have only one root
window, but additional windows can be created using the TopLevel widget.
The following table gives a list of some of the available tkinter widgets:

Building a Basic GUI


Labels are widgets that are used to display short pieces of text. Here we create a Label that
belongs to the root window—its parent widget—and we specify the text to be displayed by
assigning it to the Label’s text parameter.

import tkinter
window = tkinter.Tk()
label = tkinter.Label(window, text='This is our label.')
label.pack()
window.mainloop()

• Method call label.pack() is crucial. Each widget has a method called pack that places
it in its parent widget and then tells the parent to resize itself as necessary. If we forget to

Prepared By: Dr. Rama Satish K V, Asst Professor, RNSIT, Bengaluru


call this method, the child widget (in this case, Label) won’t be displayed or will be
displayed improperly.
• Labels display text. Often, applications will want to update a label’s text as the program
runs to show things like the name of a file or the time of day. One way to do this is simply
to assign a new value to the widget’s text using method config.

import tkinter
window = tkinter.Tk()
label = tkinter.Label(window, text='First label.')
label.pack()
label.config(text='Second label.')
window.mainloop()

Using Mutable Variables with Widgets


• Suppose you want to display a string, such as the current time or a score in a game, in
several places in a GUI—the application’s status bar, some dialog boxes, and so on.

import tkinter
window = tkinter.Tk()
data = tkinter.StringVar()
data.set('Data to display')
label = tkinter.Label(window, textvariable=data)
label.pack()
window.mainloop()

Grouping Widgets with the Frame Type


• A tkinter Frame is a container, much like the root window is a container. Frames are not
directly visible on the screen; instead, they are used to organize other widgets.
• The following code creates a frame, puts it in the root window, and then adds three Labels
to the frame:

Prepared By: Dr. Rama Satish K V, Asst Professor, RNSIT, Bengaluru


Example-1:
import tkinter
window = tkinter.Tk()
frame = tkinter.Frame(window)
frame.pack()
first = tkinter.Label(frame, text='First label')
first.pack()
second = tkinter.Label(frame, text='Second label')
second.pack()
third = tkinter.Label(frame, text='Third label')
third.pack()
window.mainloop()

Example 2:
import tkinter
window = tkinter.Tk()
frame = tkinter.Frame(window, borderwidth=4, relief=tkinter.GROOVE)
frame.pack()
first = tkinter.Label(frame, text='First label')
first.pack()
second = tkinter.Label(frame, text='Second label')
second.pack()
third = tkinter.Label(frame, text='Third label')
third.pack()
window.mainloop()
Note: The other border styles are SUNKEN, RAISED, GROOVE, and RIDGE

Getting Information from the User with the Entry Type


import tkinter
window = tkinter.Tk()
frame = tkinter.Frame(window)
frame.pack()
var = tkinter.StringVar()
label = tkinter.Label(frame, textvariable=var)
label.pack()
entry = tkinter.Entry(frame, textvariable=var)
entry.pack()
window.mainloop()

Label Widget

import tkinter
parent_widget = tkinter.Tk()
label_widget = tkinter.Label(parent_widget, text="A Label")

Prepared By: Dr. Rama Satish K V, Asst Professor, RNSIT, Bengaluru


label_widget.pack()
tkinter.mainloop()

Button Widget

import tkinter
parent_widget = tkinter.Tk()
button_widget = tkinter.Button(parent_widget, text="A Button")
button_widget.pack()
tkinter.mainloop()

Entry Widget

import tkinter
parent_widget = tkinter.Tk()
entry_widget = tkinter.Entry(parent_widget)
entry_widget.insert(0, "Type your text here")
entry_widget.pack()
tkinter.mainloop()

Radio button Widget

import tkinter
parent_widget = tkinter.Tk()
v = tkinter.IntVar()
v.set(1) # need to use v.set and v.get to
# set and get the value of this variable
radiobutton_widget1 = tkinter.Radiobutton(parent_widget, text="Radiobutton 1",
variable=v, value=1)
radiobutton_widget2 = tkinter.Radiobutton(parent_widget, text="Radiobutton 2",
variable=v, value=2)
radiobutton_widget1.pack()
radiobutton_widget2.pack()
tkinter.mainloop()

Radio button Widget

We can display a Radiobutton without the dot indicator. In that case it displays its
state by being sunken or raised.

Prepared By: Dr. Rama Satish K V, Asst Professor, RNSIT, Bengaluru


import tkinter
parent_widget = tkinter.Tk()
v = tkinter.IntVar()
v.set(1)
radiobutton_widget1 = tkinter.Radiobutton(parent_widget, text="Radiobutton 1",
variable=v, value=1, indicatoron=False)
radiobutton_widget2 = tkinter.Radiobutton(parent_widget, text="Radiobutton 2",
variable=v, value=2, indicatoron=False)
radiobutton_widget1.pack()
radiobutton_widget2.pack()
tkinter.mainloop()

Check button Widget

import tkinter
parent_widget = tkinter.Tk()
checkbutton_widget = tkinter.Checkbutton(parent_widget,
text="Checkbutton")
checkbutton_widget.select()
checkbutton_widget.pack()
tkinter.mainloop()

Scale Widget: Horizontal

import tkinter
parent_widget = tkinter.Tk()
scale_widget = tkinter.Scale(parent_widget, from_=0, to=100,
orient=tkinter.HORIZONTAL)
scale_widget.set(25)
scale_widget.pack()
tkinter.mainloop()

Scale Widget: Vertical

Prepared By: Dr. Rama Satish K V, Asst Professor, RNSIT, Bengaluru


import tkinter
parent_widget = tkinter.Tk()
scale_widget = tkinter.Scale(parent_widget, from_=0, to=100,
orient=tkinter.VERTICAL)
scale_widget.set(25)
scale_widget.pack()
tkinter.mainloop()

Text Widget

import tkinter
parent_widget = tkinter.Tk()
text_widget = tkinter.Text(parent_widget,
width=20, height=3)
text_widget.insert(tkinter.END,
"Text Widgetn20 characters widen3 lines high")
text_widget.pack()
tkinter.mainloop()

LabelFrame Widget

import tkinter
parent_widget = tkinter.Tk()
labelframe_widget = tkinter.LabelFrame(parent_widget,
text="LabelFrame")
label_widget=tkinter.Label(labelframe_widget,
text="Child widget of the LabelFrame")
labelframe_widget.pack(padx=10, pady=10)
label_widget.pack()
tkinter.mainloop()

Canvas Widget

import tkinter
parent_widget = tkinter.Tk()
canvas_widget = tkinter.Canvas(parent_widget, bg="blue", width=10,
height= 50)
canvas_widget.pack()

Prepared By: Dr. Rama Satish K V, Asst Professor, RNSIT, Bengaluru


tkinter.mainloop()

Listbox Widget

import tkinter
parent_widget = tkinter.Tk()
listbox_entries = ["Entry 1", "Entry 2",
"Entry 3", "Entry 4"]
listbox_widget = tkinter.Listbox(parent_widget)
for entry in listbox_entries:
listbox_widget.insert(tkinter.END, entry)
listbox_widget.pack()
tkinter.mainloop()

Menu Widget

import tkinter
parent_widget = tkinter.Tk()
def menu_callback():
print("I'm in the menu callback!")
def submenu_callback():
print("I'm in the submenu callback!")
menu_widget = tkinter.Menu(parent_widget)
submenu_widget = tkinter.Menu(menu_widget, tearoff=False)
submenu_widget.add_command(label="Submenu Item1",
command=submenu_callback)
submenu_widget.add_command(label="Submenu Item2",
command=submenu_callback)
menu_widget.add_cascade(label="Item1", menu=submenu_widget)
menu_widget.add_command(label="Item2", command=menu_callback)
menu_widget.add_command(label="Item3", command=menu_callback)
parent_widget.config(menu=menu_widget)
tkinter.mainloop()

Models, Views, and Controllers


• Using a StringVar to connect a text-entry box and a label is the first step toward separating
models (How do we represent the data?), views (How do we display the data?), and controllers

Prepared By: Dr. Rama Satish K V, Asst Professor, RNSIT, Bengaluru


(How do we modify the data?), which is the key to building larger GUIs (as well as many other
kinds of applications).

• This MVC design helps separate the parts of an application, which will make the application
easier to understand and modify.

• The main goal of this design is to keep the representation of the data separate from the parts of
the program that the user interacts with; that way, it is easier to make changes to the GUI code
without affecting the code that manipulates the data.

• As its name suggests, a view is something that displays information to the user, like Label.
Many views, like Entry, also accept input, which they display immediately. The key is that they
don’t do anything else: they don’t calculate average temperatures, move robot arms, or do any
other calculations.

• Models, on the other hand, store data, like a piece of text or the current inclination of a
telescope. They also don’t do calculations; their job is simply to keep track of the application’s
current state (and, in some cases, to save that state to a file or database and reload it later).

• Controllers are the pieces that convert user input into calls on functions in the model that
manipulate the data. The controller is what decides whether two gene sequences match well
enough to be colored green or whether someone is allowed to overwrite an old results file.
Controllers may update an application’s models, which in turn can trigger changes to its views.

Example :
import tkinter
# The controller.
def click_up():
counter.set(counter.get() + 1)

def click_down():
counter.set(counter.get() - 1)

# The model.
counter = tkinter.IntVar()
counter.set(0)

Prepared By: Dr. Rama Satish K V, Asst Professor, RNSIT, Bengaluru


# The views.
window = tkinter.Tk()
frame = tkinter.Frame(window)
frame.pack()
button = tkinter.Button(frame, text='Up', command=click_up)
button.pack()
label = tkinter.Label(frame, textvariable=counter)
label.pack()
button = tkinter.Button(frame, text='Down', command=click_down)
button.pack()

window.mainloop()

Lambda Functions
• The name lambda function comes from lambda calculus, a mathematical system for
investigating function definition and application that was developed in the 1930s by
Alonzo Church and Stephen Kleene.
• The lambda form does not create a new variable or change an existing one. Finally,
lambda functions can take arguments, just like other functions:

• The simple counter GUI shown earlier does what it’s supposed to, but there is room for
improvement.
• For example, suppose we want to be able to lower the counter’s value as well as raise it.
• So how does this help us with GUIs? The answer is that it lets us write one controller
function to handle different buttons in a general way and then wrap up calls to that
function when and as needed. Here’s the two-button GUI once again using lambda
functions:
import tkinter
# The controller.
def click(var, value):
var.set(var.get() + value)
# The model.
counter = tkinter.IntVar()
counter.set(0)
# The views.
window = tkinter.Tk()
frame = tkinter.Frame(window)

Prepared By: Dr. Rama Satish K V, Asst Professor, RNSIT, Bengaluru


frame.pack()
button= tkinter.Button(frame, text='Up',
command=lambda: click(counter, 1))
button.pack()
button= tkinter.Button(frame, text='Down',
command=lambda: click(counter, -1))
button.pack()
label = tkinter.Label(frame, textvariable=counter)
label.pack()
window.mainloop()

Customizing the Visual Style


Every windowing system has its own look and feel—square or rounded corners, particular colors,
and so on. In this section, we’ll see how to change the appearance of GUI widgets to make
applications look more distinctive. A note of caution before we begin: the default styles of some
windowing systems have been chosen by experts trained in graphic design and human computer
interaction. The odds are that any radical changes on your part will make things worse, not better.
In particular, be careful about color (several percent of the male population has some degree of
color blindness) and font size (many people, particularly the elderly, cannot read small text).

Changing Fonts
Let’s start by changing the size, weight, slant, and family of the font used to display text. To specify
the size, we provide the height as an integer in points. We can set the weight to either bold or
normal and the slant to either italic (slanted) or roman (not slanted). The font families we can use
depend on what system the program is running on. Common families include Times, Courier, and
Verdana, but dozens of others are usually available. One note of caution though: if you choose an
unusual font, people running your program on other computers might not have it, so your GUI
might appear different than you’d like for them. Every operating system has a default font that will
be used if the requested font isn’t installed.

The following sets the font of a button to be 14 point, bold, italic, and Courier.
import tkinter
window = tkinter.Tk()
button = tkinter.Button(window, text='Hello',
font=('Bookman', 14, 'bold italic'))
button.pack()
window.mainloop()

Prepared By: Dr. Rama Satish K V, Asst Professor, RNSIT, Bengaluru


Changing Colors
Almost all foreground colors can be set using the bg and fg keyword arguments, respectively. As
the following code shows, we can set either of these to a standard color by specifying the color’s
name, such as white, black, red, green, blue, cyan, yellow, or magenta:

import tkinter
window = tkinter.Tk()
button = tkinter.Label(window, text='Hello', bg='green', fg='white')
button.pack()
window.mainloop()

We can choose more colors by specifying them using the RGB color model. RGB is an
abbreviation for “red, green, blue”; it turns out that every color can be created using different
amounts of these three colors. The amount of each color is usually specified by a number between
0 and 255 (inclusive).

These numbers are conventionally written in hexadecimal (base 16) notation; the best way to
understand them is to play with them. Base 10 uses the digits 0 through 9; base 16 uses those ten
digits plus another six: A, B, C, D, E, and F. In base 16, the number 255 is written FF. The following
color picker does this by updating a piece of text to show the color specified by the red, green, and
blue values entered in the text boxes; choose any two base-16 digits for the RGB values and click
the Update button:

import tkinter
def change(widget, colors):
""" Update the foreground color of a widget to show the RGB color value
stored in a dictionary with keys 'red', 'green', and 'blue'. Does
*not* check the color value.
"""
new_val = '#'
for name in ('red', 'green', 'blue'):
new_val += colors[name].get()
widget['bg'] = new_val

# Create the application.


window = tkinter.Tk()
frame = tkinter.Frame(window)
frame.pack()

Prepared By: Dr. Rama Satish K V, Asst Professor, RNSIT, Bengaluru


# Set up text entry widgets for red, green, and blue, storing the
# associated variables in a dictionary for later use.
colors = {}
for (name, col) in (('red', '#FF0000'),
('green', '#00FF00'),
('blue', '#0000FF')):
colors[name] = tkinter.StringVar()
colors[name].set('00')
entry = tkinter.Entry(frame, textvariable=colors[name], bg=col,
fg='white')
entry.pack()
# Display the current color.
current = tkinter.Label(frame, text=' ', bg='#FFFFFF')
current.pack()

# Give the user a way to trigger a color update.


update = tkinter.Button(frame, text='Update',
command=lambda: change(current, colors))
update.pack()
tkinter.mainloop()

Laying Out the Widgets


One of the things that makes the color picker GUI ugly is the fact that everything is arranged top
to bottom. tkinter uses this layout by default, but we can usually come up with something better.
let’s revisit the example from placing the label and button horizontally. We tell tkinter to do this
by providing a side argument to method pack:

import tkinter
window = tkinter.Tk()
frame = tkinter.Frame(window)
frame.pack()
label = tkinter.Label(frame, text='Name')
label.pack(side='left')
entry = tkinter.Entry(frame)
entry.pack(side='left')
window.mainloop()

Prepared By: Dr. Rama Satish K V, Asst Professor, RNSIT, Bengaluru


Setting side to "left" tells tkinter that the leftmost part of the label is to be placed next to
the left edge of the frame, and then the leftmost part of the entry field is placed next to the right
edge of the label—in short, that widgets are to be packed using their left edges. We could equally
well pack to the right, top, or bottom edges, or we could mix packings.

For even more control of our window layout, we can use a different layout manager called grid.
As its name implies, it treats windows and frames as grids of rows and columns. To add the widget
to the window, we call grid instead of pack. Do not call both on the same widget; they conflict
with each other. The grid call can take several parameters, as shown in Table, grid()
Parameters.

import tkinter
window = tkinter.Tk()
frame = tkinter.Frame(window)
frame.pack()
label = tkinter.Label(frame, text='Name:')
label.grid(row=0, column=0)
entry = tkinter.Entry(frame)
entry.grid(row=1, column=1)
window.mainloop()

Object-Oriented GUIs
• The GUIs we have built so far have not been particularly well structured. Most of the code
to construct them has not been modularized in functions, and they have relied on global
variables. We can get away with this for very small examples, but if we try to build larger
applications this way, they will be difficult to understand and debug.
• For this reason, almost all real GUIs are built using classes and objects that tie models,
views, and controllers together in one tidy package. In the counter shown next, for example,
the application’s model is a member variable of class Counter, accessed using self.state,
and its controllers are the methods upClick and quitClick.

Prepared By: Dr. Rama Satish K V, Asst Professor, RNSIT, Bengaluru


import tkinter

class Counter:
"""A simple counter GUI using object-oriented programming."""
def __init__(self, parent):

"""Create the GUI."""

# Framework.
self.parent = parent
self.frame = tkinter.Frame(parent)
self.frame.pack()

# Model.
self.state = tkinter.IntVar()
self.state.set(1)

# Label displaying current state.


self.label = tkinter.Label(self.frame, textvariable=self.state)
self.label.pack()

# Buttons to control application.


self.up = tkinter.Button(self.frame,
text='up', command=self.up_click)
self.up.pack(side='left')
self.down = tkinter.Button(self.frame,
text='down', command=self.down_click)
self.down.pack(side='left')

self.right = tkinter.Button(self.frame, text='quit',


command=self.quit_click)
self.right.pack(side='left')

def up_click(self):
"""Handle click on 'up' button."""
self.state.set(self.state.get() + 1)

def down_click(self):
"""Handle click on 'down' button."""
self.state.set(self.state.get() - 1)

def quit_click(self):
"""Handle click on 'quit' button."""
self.parent.destroy()

if __name__ == '__main__':

window = tkinter.Tk()
myapp = Counter(window)
window.mainloop()

Prepared By: Dr. Rama Satish K V, Asst Professor, RNSIT, Bengaluru


Keeping the Concepts from Being a GUI Mess
In this chapter, you learned the following:
• Most modern programs provide a graphical user interface (GUI) for displaying information
and interacting with users. GUIs are built out of widgets, such as buttons, sliders, and text
panels; all modern programming languages provide at least one GUI toolkit.
• Unlike command-line programs, GUI applications are usually event-driven. In other words,
they react to events such as keystrokes and mouse clicks when and as they occur.
• Experience shows that GUIs should be built using the model-view-controller pattern. The
model is the data being manipulated; the view displays the current state of the data and
gathers input from the user, while the controller decides what to do next.
• Lambda expressions create functions that have no names. These are often used to define
the actions that widgets should take when users provide input, without requiring global
variables.
• Designing usable GUIs is as challenging a craft as designing software. Being good at the
latter doesn’t guarantee that you can do the former, but dozens of good books can help you
get started.
--- 000 ---

Prepared By: Dr. Rama Satish K V, Asst Professor, RNSIT, Bengaluru

You might also like