avatarEdward Jones

Summary

The provided website content is a comprehensive guide for Python developers to build a user-friendly document generator GUI application using Tkinter.

Abstract

The article is the second part of a three-part Python series titled "Build Your Own Application in Python." It focuses on creating a graphical user interface (GUI) using the Tkinter package for a document generator application. The guide walks through the necessary steps, starting with importing libraries and defining the create_gui function, to setting up the main window, configuring button styles, and creating containers for widgets. It details the process of defining variables for user inputs, creating labels, entry fields, and browse buttons, and explains how to generate reports with a click of a button. The tutorial emphasizes user convenience, allowing users to fill in templates with data from an Excel file, and provides downloadable example files to follow along with the code. The article concludes by showcasing the end result of the GUI and encouraging users to explore and customize the GUI to meet their specific needs.

Opinions

  • The tutorial is designed to be user-friendly, assuming that the reader may be new to GUI development with Tkinter.
  • The methodology emphasizes the importance of creating a clean and intuitive interface for applications that require user input and file handling.
  • The author believes in the practicality of learning by doing, providing hands-on examples and downloadable resources for readers to practice with.
  • The article promotes the use of enhanced widget styles provided by the ttk submodule for a more modern and polished look of the GUI.
  • The guide suggests that automating document generation through a GUI can significantly improve efficiency and user experience.
  • The conclusion of the article expresses confidence in the reader's ability to implement the knowledge gained from the tutorial to create their own GUI applications.

Master Python GUI Development with Tkinter

Step-by-step guide to building a user-friendly document generator GUI in Python

Example of a GUI designed in Tkinter with Python

Welcome to the second part of our three-part Python series, “Build Your Own Application in Python.” In this installment, we’ll guide you through creating a graphical user interface (GUI) using the Tkinter package.

If you’re new to this series, you can catch up on the first part here:

  1. Automate Filling in Word Templates Using Python
  2. Create a Graphical User Interface (GUI) using the Tkinter package
  3. Python Code to Standalone Executable: How to Use PyInstaller
Part two of the three-part article series

Methodology

This article’ll walk you through the steps to create a GUI for a document generator application. The script we’ll develop allows users to fill in templates with data from an Excel file, select input and output folders conveniently, and generate reports with just a few clicks.

Downloadable files

Before we dive into the code, you can download the example files we’ll be using at these links:

Word template

Excel template

These files will help you follow along with the code and understand how the GUI interacts with them.

Step 1: Import necessary libraries

To get started, you need to import the necessary libraries:

import tkinter as tk
from tkinter import ttk
from functools import partial
  • tkinter: This library provides you with tools for creating GUI applications.
  • ttk: A submodule of tkinter that offers enhanced widget styles.
  • functools.partial: You can use this to create functions with predefined arguments.

Step 2: Define the create_gui function

You then define a function called create_gui that will create the graphical user interface.

def create_gui():

Step 3: Set up the main window

  • You declare success_label as a global variable so that you can access it inside functions.
  • You create the main application window (root) and set its title to "Document Generator."
    global success_label  # Declare success_label as a global variable
    root = tk.Tk()
    root.title("Document Generator")

Step 4: Configure button style

Here, you configure the style of buttons in the GUI. They will have padding and a flat relief style.

    style = ttk.Style()
    style.configure('TButton', padding=10, relief="flat")

Step 5: Create a container for widgets

Now, create a container (a frame) to hold all the widgets in the GUI, set padding, and arrange it using a grid layout.

    container = ttk.Frame(root, padding=20)
    container.grid(column=0, row=0, sticky=(tk.W, tk.E, tk.N, tk.S))

Step 6: Define variables for user inputs

Create three StringVar variables to store your input for the input folder, Excel file, and output folder.

    input_folder_var = tk.StringVar()
    excel_file_var = tk.StringVar()
    output_folder_var = tk.StringVar()

Step 7: Create labels and entry fields for input

For the input folder, create a label and an entry field. Labels display text, while entry fields allow you to input text.

    input_folder_label = ttk.Label(container, text="Input Folder:")
    input_folder_entry = ttk.Entry(container, textvariable=input_folder_var)

Step 8: Add a browse button for input folder

Create a “Browse” button that, when clicked, calls a function (select_input_folder) to select an input folder.

    input_folder_button = ttk.Button(container, text="Browse", command=partial(select_input_folder, input_folder_var))

Step 9: Repeat steps 7 and 8 for Excel file and output folder

Repeat the same steps for the Excel file and output folder, creating labels, entry fields, and browse buttons (see the full code below).

Step 10: Create a button to generate reports

Create a button labeled “Generate Reports” that, when clicked, will call a function (generate_reports) to generate reports based on your input data.

    generate_button = ttk.Button(container, text="Generate Reports", command=partial(generate_reports, input_folder_var, excel_file_var, output_folder_var))

Step 11: Create a label for success message

Create a label displaying a success message when the reports are generated.

    success_label = ttk.Label(container, text="")

Step 12: Configure widget placement and appearance

To ensure a consistent appearance, configure the placement and appearance of all widgets within the container.

    for child in container.winfo_children():
        child.grid_configure(padx=5, pady=5)

Step 13: Start the GUI application

Now, start the main event loop, which keeps the GUI running and responsive to your interactions.

    root.mainloop()

Step 14: Run the GUI if the script is executed directly

Finally, add a conditional block to ensure that the create_gui function is called only if the script is executed directly (not imported as a module).

if __name__ == '__main__':
    create_gui()

That’s it! You now understand how the script creates a GUI for a “Document Generator” application. Users can input paths, select files, and generate reports through this user-friendly interface.

The end result should look like this

Conclusion

In this article, we’ve walked you through creating a GUI for a document generator application using Python and Tkinter. You’ve learned how to set up the GUI, handle user inputs, and trigger actions with the click of a button. Feel free to explore and customize the GUI to suit your needs.

Happy coding!

Graphical interface code block

Word template

Excel template

import os
from openpyxl import load_workbook
from docx import Document
from docxtpl import DocxTemplate
import tkinter as tk
from tkinter import ttk, messagebox
from tkinter import filedialog
from functools import partial

success_label = None

def generate_report(input_folder, excel_file, output_folder):
    """
    Generate reports based on Excel data and a Word template.
    """
    # Define the template path
    template_path = os.path.join(input_folder, 'Template.docx')

    # Load the Excel workbook and template
    workbook = load_workbook(excel_file)
    template = DocxTemplate(template_path)
    worksheet = workbook["Template"]

    # Placeholder values for data to fill into the template
    to_fill_in = {
    "BUSINESS_NAME": None,
    "Date": None,
    "Customer": None,
    "Customer_ID": None,
    "Address": None,
    "Phone": None,
    "Recipient": None,
    "Payment_Due": None,
    "Salesperson": None,
    "Payment_Terms": None,
    "Delivery_Date": None,
    "Shipping_Method": None,
    "Shipping_Terms": None
}


    # Iterate over columns in the worksheet
    column = 2
    print(worksheet.max_column)
    while column <= worksheet.max_column:
        col_index = chr(column + 64)
        row_index = 1

         # Retrieve the values from the Excel document and store in dict
        for key in to_fill_in:
            cell = '%s%i' % (col_index, row_index)
            to_fill_in[key] = worksheet[cell].value
            row_index += 1

        # Change the words in the template
        template.render(to_fill_in)

         # Output the file to a DOCX document
        filename = str(to_fill_in['BUSINESS_NAME']) + '.docx'
        filled_path = os.path.join(output_folder, filename)
        template.save(filled_path)
        print("Done with %s" % str(to_fill_in['BUSINESS_NAME']))
        column += 1




# Define success_label as a global variable
success_label = None

def select_input_folder(input_folder_var):
    folder = filedialog.askdirectory()
    input_folder_var.set(folder)

def select_excel_file(excel_file_var):
    file = filedialog.askopenfilename(filetypes=[("Excel files", "*.xlsx")])
    excel_file_var.set(file)

def select_output_folder(output_folder_var):
    folder = filedialog.askdirectory()
    output_folder_var.set(folder)

def generate_reports(input_folder_var, excel_file_var, output_folder_var):
    input_folder = input_folder_var.get()
    excel_file = excel_file_var.get()
    output_folder = output_folder_var.get()

    generate_report(input_folder, excel_file, output_folder)

    # Call other report generation functions here if needed

    # Show success message
    success_label.config(text="Reports generated successfully!")

def create_gui():
    global success_label  # Declare success_label as a global variable
    root = tk.Tk()
    root.title("Document Generator")

    style = ttk.Style()
    style.configure('TButton', padding=10, relief="flat")

    container = ttk.Frame(root, padding=20)
    container.grid(column=0, row=0, sticky=(tk.W, tk.E, tk.N, tk.S))

    input_folder_var = tk.StringVar()
    excel_file_var = tk.StringVar()
    output_folder_var = tk.StringVar()

    input_folder_label = ttk.Label(container, text="Input Folder:")
    input_folder_label.grid(column=0, row=0, sticky=tk.W)

    input_folder_entry = ttk.Entry(container, textvariable=input_folder_var)
    input_folder_entry.grid(column=0, row=1, columnspan=2, sticky=(tk.W, tk.E))

    input_folder_button = ttk.Button(container, text="Browse", command=partial(select_input_folder, input_folder_var))
    input_folder_button.grid(column=2, row=1, sticky=tk.W)

    excel_file_label = ttk.Label(container, text="Excel File:")
    excel_file_label.grid(column=0, row=2, sticky=tk.W)

    excel_file_entry = ttk.Entry(container, textvariable=excel_file_var)
    excel_file_entry.grid(column=0, row=3, columnspan=2, sticky=(tk.W, tk.E))

    excel_file_button = ttk.Button(container, text="Browse", command=partial(select_excel_file, excel_file_var))
    excel_file_button.grid(column=2, row=3, sticky=tk.W)

    output_folder_label = ttk.Label(container, text="Output Folder:")
    output_folder_label.grid(column=0, row=4, sticky=tk.W)

    output_folder_entry = ttk.Entry(container, textvariable=output_folder_var)
    output_folder_entry.grid(column=0, row=5, columnspan=2, sticky=(tk.W, tk.E))

    output_folder_button = ttk.Button(container, text="Browse", command=partial(select_output_folder, output_folder_var))
    output_folder_button.grid(column=2, row=5, sticky=tk.W)

    generate_button = ttk.Button(container, text="Generate Reports", command=partial(generate_reports, input_folder_var, excel_file_var, output_folder_var))
    generate_button.grid(column=0, row=6, columnspan=3, pady=10)

    # Label to display success message
    success_label = ttk.Label(container, text="")
    success_label.grid(column=0, row=7, columnspan=3)

    for child in container.winfo_children():
        child.grid_configure(padx=5, pady=5)

    root.mainloop()

if __name__ == '__main__':
    create_gui()
Python
Programming
Automation
Recommended from ReadMedium
avatarWHAT TO KNOW
Python GUI: PyQt vs Tkinter

5 min read