Building a Python GUI app to extract unique lines from multiple sets of text files

Javelin
3 min readNov 8, 2024

--

In this tutorial, we will create a simple Python GUI application using Tkinter that allows users to extract unique lines from multiple text files. The application will support drag-and-drop functionality for file selection and will provide options to remove duplicates, delete selected files, and clear the list of files.

Github Link

Download Program

Prerequisites

Before we start, ensure you have the following installed:

  • Python 3.x
  • Tkinter (usually included with Python)
  • tkinterdnd2 for drag-and-drop functionality
  • Pillow for image handling

You can install the required packages using pip:

pip install tkinterdnd2 Pillow

Step-by-Step Guide

Step 1: Import Required Libraries

We will start by importing the necessary libraries:

import tkinter as tk
from tkinter import filedialog, messagebox, Listbox, Scrollbar
from tkinterdnd2 import DND_FILES, TkinterDnD
import os
import base64
from PIL import Image, ImageTk
import io

Step 2: Create the Main Application Class

Next, we will create a class UniqueLinesApp that will handle the GUI and functionality of our application.

class UniqueLinesApp:
def __init__(self, master):
self.master = master
self.master.title("Unique Lines")
self.master.geometry("400x400")
self.set_icon() # Set the application icon
self.file_list = [] # List to store file paths

# Create a Listbox to display the files
self.listbox = Listbox(master, selectmode=tk.SINGLE)
self.listbox.pack(pady=20, fill=tk.BOTH, expand=True)

# Add a scrollbar
self.scrollbar = Scrollbar(master)
self.scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
self.listbox.config(yscrollcommand=self.scrollbar.set)
self.scrollbar.config(command=self.listbox.yview)

# Create buttons for various actions
self.remove_button = tk.Button(master, text="Remove Duplicate Lines", command=self.remove_duplicates)
self.remove_button.pack(pady=10)

self.delete_button = tk.Button(master, text="Delete Selected File", command=self.delete_selected_file)
self.delete_button.pack(pady=5)

self.clear_button = tk.Button(master, text="Clear List", command=self.clear_list)
self.clear_button.pack(pady=5)

# Status label for messages
self.status_label = tk.Label(master, text="", fg="green")
self.status_label.pack(pady=5)

# Enable drag and drop
self.setup_drag_and_drop()

# Bind the Delete key to the delete_selected_file method
self.master.bind('<Delete>', self.on_delete_key)

Step 3: Set the Application Icon

We will set an icon for our application using a base64 encoded image. You can replace the base64 string with your own image.

    def set_icon(self):
base64_icon = "iVBORw0KGgoAAAANSUhEUgA==" # Replace with your actual base64 string
image_data = base64.b64decode(base64_icon)
image = Image.open(io.BytesIO(image_data))
image = image.resize((16, 16), Image.LANCZOS)
self.icon = ImageTk.PhotoImage(image)
self.master.iconphoto(False, self.icon)

Step 4: Implement Drag-and-Drop Functionality

We will implement drag-and-drop functionality to allow users to add files easily.

    def setup_drag_and_drop(self):
self.master.drop_target_register(DND_FILES)
self.master.dnd_bind('<<Drop>>', self.on_drop)

def on_drop(self, event):
files = self.master.tk.splitlist(event.data)
for file in files:
if os.path.isfile(file) and file not in self.file_list:
self.file_list.append(file)
self.listbox.insert(tk.END, file)

Step 5: Remove Duplicate Lines

The core functionality of our application is to remove duplicate lines from the selected text files. We will implement this in the remove_duplicates method.

    def remove_duplicates(self):
if not self.file_list:
self.update_status("No files to process.")
return

unique_lines = set()
for file in self.file_list:
with open(file, 'r', encoding='utf-8') as f:
lines = f.readlines()
unique_lines.update(line.strip() for line in lines)

# Ask user for the save location
save_path = filedialog.asksaveasfilename(defaultextension=".txt",
filetypes=[("Text files", "*.txt"),
("All files", "*

Step 6: Additional Methods for File Management

We will now add methods to manage the list of files, including deleting selected files, handling the delete key, clearing the list, and updating the status message.

Delete Selected File: This method removes the selected file from the list.

 def delete_selected_file(self):
selected_index = self.listbox.curselection()
if selected_index:
file_to_remove = self.listbox.get(selected_index)
self.file_list.remove(file_to_remove)
self.listbox.delete(selected_index)
else:
self.update_status("No file selected to delete.")

Handle Delete Key: This method allows users to delete a selected file using the Delete key.

 def on_delete_key(self, event):
self.delete_selected_file()

Clear List: This method clears all files from the list.

 def clear_list(self):
self.file_list.clear()
self.listbox.delete(0, tk.END)

Update Status:

This method updates the status label to provide feedback to the user.

 def update_status(self, message):
self.status_label.config(text=message)
self.master.after(3000, lambda: self.status_label.config(text="")) # Clear message after 3 seconds

Step 7: Main Block

Finally, ensure you have the following main block at the end of your script to run the application:

if __name__ == "__main__":
root = TkinterDnD.Tk()
app = UniqueLinesApp(root)
root.mainloop()

Summary

In this tutorial, we have built a Python GUI application that allows users to extract unique lines from multiple text files. The application supports drag-and-drop functionality for file selection and provides options to remove duplicates, delete selected files, and clear the list of files. The status label gives feedback to the user about the actions performed.

By following these steps, you should have a fully functional application that enhances the user experience when working with text files.

--

--

No responses yet