How to Create a GUI in Python with Tkinter

How to Create a GUI in Python with Tkinter

Tkinter enables you to create user interfaces for Python applications. In this tutorial, we will see how to use Tkinter and build interactive interfaces.

By the end of this tutorial:

  • You would have an understanding of the Tkinter package.
  • You would know the different types of layouts that are supported.
  • You would have an understanding how to make the interface interactive.

Let’s dive in!

Installing and setting up Tkinter

Tkinter is included with Python 3.x by default. You don’t need to install it separately. However, if your installation is missing or you are using an older version, use this command:

sudo apt-get install python-tk        

You can verify your installation like this:

python3 -m tkinter        

Once verified, window demonstrating a simple Tk interface should pop-up.

Demo window

Getting started with Tkinter

To use Tkinter in your Python applications, import the tkinter module:

import tkinter        

Creating a window

Now, let’s create a window by defining a window variable.

The complete code should look like this:

import tkinter 

if __name__ == "__main__":
    window = tkinter.Tk()
    window.mainloop()        

In the code above:

  • if __name__ == “__main__:” definition is the building block of the program. This block would also contain our widgets later on.
  • window=tkinter.Tk() creates a window object.
  • window.mainloop() is an infinite loop that tkinterruns and listens for events. It exits only when you close the window.

The output would be a blank window as shown below:

blank tkinter window

Adding title to the window

You can add a descriptive title to your window like this:

window.title("My first app")        
Adding title to the window

Resizing the window

You can resize the window by providing dimensions in the window.geometry() function.

window.geometry("800x600")        

The above code sets the window dimension to 800x600 .

Adding widgets to the window

Widgets include buttons, labels, text boxes, etc. We’ll see how to add them.

Adding labels to the window

We define a label using the Label object. We have passed the window argument that we created earlier as an argument and the text as “Hello World”.

Note that we need to explicitly add widgets to the interface using pack() , otherwise they wont be visible on the screen.


label = tkinter.Label(window, text="Hello World")
label.pack() # add to interface using pack()        
Adding label to the window

Adding buttons to the window

Buttons can be added just like we added the label.

button = tkinter.Button(window, text="Click me!")
button.pack()        
Adding button

Understanding widget hierarchy

Building UIs with Tkinter follows a hierarchy. It can go to multiple levels. The root is always the main window. Inside a window, you can nest frames and inside frames, you can add widgets. Frame is like a container for a group of widgets.

Let’s modify our existing code to include the widgets inside a frame:

import tkinter 

if __name__ == "__main__":
    window = tkinter.Tk()
    window.title("My first app")
    window.geometry("400x400")

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

    label = tkinter.Label(frame, text="Hello World")
    label.pack() 

    button = tkinter.Button(frame, text="Click me!")
    button.pack()
    print(str(button))

    window.mainloop()        

In the code above, note that the widgets now use frame as their container rather than windows .

If you run this code and the output of the line print(str(button)), you’ll be able to see the hierarchy in the console like this:

# console output of print(str(button))
.!frame.!button        

Working with text boxes

Text boxes are editable regions that can capture user input. Text boxes can be defined using .Entyr():

textBox = tkinter.Entry(frame)
textBox.pack()        

You can disable the state of a text box using the disabled property:

textBox = tkinter.Entry(frame, state="disabled")        

If you are entering a password, the text can be hidden by setting show=”*”:

 textBox = tkinter.Entry(frame, show="*")        
Hide input in a text box

Handling interactivity

Adding button click events

Notice the command=buttonEvent argument in the syntax for creating the button. This is the name of the function that would be triggered once the button is clicked.

button = tkinter.Button(frame, text="Click me!", command=buttonEvent)        

Now, define the function outside if __name__ == “main”.

def buttonEvent():
    print("Button clicked!")        
Adding event listeners

Capturing text box input

It is possible to get the text from a text box using textBox.get().

import tkinter 

if __name__ == "__main__":
    window = tkinter.Tk()

    def buttonEvent():
        # capture input from a text box
        print(textBox.get())

    window.title("My first app")
    window.geometry("400x400")

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

    label = tkinter.Label(frame, text="Hello World")
    label.pack() 

    button = tkinter.Button(frame, text="Click me!", command=buttonEvent)
    button.pack()

    textBox = tkinter.Entry(frame)
    textBox.pack()

    window.mainloop()        
Capturing user input

Understanding position with pack(), place() and grid()

We have seen previously that widgets are not visible unless you add them to the a container. You can add widgets using either pack(), place() or grid().

Positioning widgets using pack()

A widget, let’s say a button can be added using pack() as shown below:

button = tkinter.Button(frame, text="Click me!", command=buttonEvent)
button.pack()        

Pack is responsive, meaning it also centers the widgets when screen is resized.

Positioning widgets using place()

place() uses absolute positioning. The x and y coordinates are defined relative to the top left corner that is 0,0 . To displace and element across x and y axis , provide arguments in the place() method.

    label = tkinter.Label(window, text="Hello World")
    label.place(x=0, y=0) 

    textBox = tkinter.Entry(window)

    # displace x by 100 and y by 200
    textBox.place(x=100, y=200)

    button = tkinter.Button(window, text="Click me!", command=buttonEvent)
    # displace x by 100 and y by 150
    button.place(x=100, y=150)        
Positioning widgets using place()

place()is not responsive, and this is a drawback. Layout created using place()also differs on different platforms and machines.

Positioning widgets using grid()

grid() uses a 2D grid as shown below:

Passing the row and column number in grid() specifies the widget position. width_textBox.grid(row=0, column=1) places the text box in the first row and second column.

Look at the complete code:

    # define widgets
    width_label = tkinter.Label(window, text="Width of rectangle")
    width_textBox = tkinter.Entry(window)

    height_label = tkinter.Label(window, text="Height of rectangle")
    height_textBox = tkinter.Entry(window)

    button = tkinter.Button(window, text="Calculate area", command=buttonEvent)
    
    # add widgets using grid
    width_label.grid(row=0, column=0)
    width_textBox.grid(row=0, column=1)

    height_label.grid(row=1, column=0)
    height_textBox.grid(row=1, column=1)

    # colspan spreads the button to two columns and centers it
    button.grid(row=2, column=0, columnspan=2)
        
Layout created using grid()

Grid layout is however not responsive.

Building your first Python GUI application- currency converter

Now it’s time to build a project. We would build a simple currency calculator that takes two inputs being the current currency and the desired currency. After applying the currency rate, we would display the result.

For the projetc, we would be adding the following widgets:

  • Entry or text box.
  • Buttons
  • Labels

We would create the layout using grid().

Steps

  1. Import Libraries:

Import the necessary libraries:

  • tkinter for creating the GUI.

import tkinter as tk        

2. Create a Class for Currency Converter:

Define a class called CurrencyConverter to encapsulate the functionality of the currency converter.

class CurrencyConverter:        

3. Initialize the GUI:

In the constructor (__init__), initialize the GUI window with the title "Currency Converter."

def __init__(self, window):
    self.window = window
    self.window.title("Currency Converter")        

4. Get Currency Data (Placeholder):

Define a currency_data attribute and populate it with a call to get_currency_data. In this example, it’s just a placeholder for currency conversion rates, but in a real application, you can also fetch this data from an API.

self.currency_data = self.get_currency_data()        

5. Create Tkinter Variables for Currency and Amount:

We create Tkinter variables for the from currency, to currency, amount to convert, and the result.

self.from_currency_var = tk.StringVar()
self.to_currency_var = tk.StringVar()
self.amount_var = tk.DoubleVar()
self.result_var = tk.DoubleVar()        

6. Create GUI Widgets:

Call a method create_widgets() to create the GUI elements.

self.create_widgets()        

7. Fetch Currency Data (Placeholder):

This is a random conversion rate.

def get_currency_data(self):
     return {'USD': 1.0, 'EUR': 0.85, 'JPY': 110.0, 'GBP': 0.72}        

8. Create GUI Elements:

Create label widgets for “From Currency,” “To Currency,” “Amount,” and “Converted Amount.”

def create_widgets(self):
    # Labels
    from_label = tk.Label(self.window, text="From Currency:")
    to_label = tk.Label(self.window, text="To Currency:")
    amount_label = tk.Label(self.window, text="Amount:")
    result_label = tk.Label(self.window, text="Converted Amount:")
    

        

9. Create Entry Fields:

We create entry fields for user input where they can specify the from currency, to currency, and the amount to convert.

    from_entry = tk.Entry(self.window, textvariable=self.from_currency_var)
    to_entry = tk.Entry(self.window, textvariable=self.to_currency_var)
    amount_entry = tk.Entry(self.window, textvariable=self.amount_var)
    result_entry = tk.Entry(self.window, textvariable=self.result_var)
    
        

10. Position GUI Elements in a Grid:

Use the .grid()method to position the labels and entry fields in a grid layout.

    from_label.grid(row=0, column=0)
    to_label.grid(row=1, column=0)
    amount_label.grid(row=2, column=0)
    result_label.grid(row=3, column=0)

    from_entry.grid(row=0, column=1)
    to_entry.grid(row=1, column=1)
    amount_entry.grid(row=2, column=1)
    result_entry.grid(row=3, column=1)        

11. Create a Conversion Method:

Define a convert method, which is called when the "Convert" button is pressed. It retrieves the input data, performs the currency conversion, and updates the result entry field.

def convert(self):
    from_currency = self.from_currency_var.get()
    to_currency = self.to_currency_var.get()
    amount = self.amount_var.get()

    if from_currency != to_currency:
        try:
            converted_amount = amount * (self.currency_data[to_currency] / self.currency_data[from_currency])
            self.result_var.set(round(converted_amount, 2))
        except KeyError:
            self.result_var.set("Currency not found")
    else:
        self.result_var.set(amount)        

12. Main Application Entry Point:

Finally, we check if the script is the main entry point and if so, create a Tkinter root window, instantiate the CurrencyConverter class, and start the main GUI event loop with root.mainloop().

if __name__ == "__main__":
    root = tk.Tk()
    currency_converter = CurrencyConverter(root)
    root.mainloop()        

Complete code:

import tkinter as tk

class CurrencyConverter:
    def __init__(self, window):
        self.window = window
        self.window.title("Currency Converter")

        self.currency_data = self.get_currency_data()

        self.from_currency_var = tk.StringVar()
        self.to_currency_var = tk.StringVar()
        self.amount_var = tk.DoubleVar()
        self.result_var = tk.DoubleVar()

        self.create_widgets()

    def get_currency_data(self):
        return {'USD': 1.0, 'EUR': 0.85, 'JPY': 110.0, 'GBP': 0.72}

    def create_widgets(self):
        # Label
        from_label = tk.Label(self.window, text="From Currency:")
        to_label = tk.Label(self.window, text="To Currency:")
        amount_label = tk.Label(self.window, text="Amount:")
        result_label = tk.Label(self.window, text="Converted Amount:")

        from_label.grid(row=0, column=0)
        to_label.grid(row=1, column=0)
        amount_label.grid(row=2, column=0)
        result_label.grid(row=3, column=0)

        # Entry
        from_entry = tk.Entry(self.window, textvariable=self.from_currency_var)
        to_entry = tk.Entry(self.window, textvariable=self.to_currency_var)
        amount_entry = tk.Entry(self.window, textvariable=self.amount_var)
        result_entry = tk.Entry(self.window, textvariable=self.result_var)

        from_entry.grid(row=0, column=1)
        to_entry.grid(row=1, column=1)
        amount_entry.grid(row=2, column=1)
        result_entry.grid(row=3, column=1)

        # Convert button
        convert_button = tk.Button(self.window, text="Convert", command=self.convert)
        convert_button.grid(row=4, column=0, columnspan=2)

    def convert(self):
        from_currency = self.from_currency_var.get()
        to_currency = self.to_currency_var.get()
        amount = self.amount_var.get()

        if from_currency != to_currency:
            try:
                # Calculate the converted amount using the exchange rates
                converted_amount = amount * (self.currency_data[to_currency] / self.currency_data[from_currency])
                self.result_var.set(round(converted_amount, 2))
            except KeyError:
                self.result_var.set("Currency not found")
        else:
            self.result_var.set(amount)

if __name__ == "__main__":
    root = tk.Tk()
    currency_converter = CurrencyConverter(root)
    root.mainloop()        



Conclusion

And there we have it. I hope you have found this useful. Thank you for reading.

要查看或添加评论,请登录

Zaira H.的更多文章

社区洞察

其他会员也浏览了