In this tutorial, weβll build a Random Username Generator using Python, Tkinter, and threading. The app allows users to generate usernames in different styles, filter, sort, and copy them easily.
Weβll break it into digestible steps for beginners.
1οΈβ£ Setting Up the Project
First, create a new Python file called username_generator.py and make sure you have Python 3.9+ installed.
Weβll import all the libraries we need:
import os
import json
import random
import string
import tkinter as tk
from tkinter import ttk, messagebox
import sv_ttk # pip install sv-ttk
from threading import Thread
Explanation:
os & json β To save and load usernames from a file.
random & string β For generating random usernames.
tkinter β The main GUI toolkit.
sv_ttk β A modern light/dark theme for Tkinter.
Thread β To run username generation without freezing the GUI.
2οΈβ£ Helper Functions
Weβll create functions to load, save, and generate usernames.
CONFIG_FILE = "usernames_data.json"
def load_usernames():
"""Load saved usernames from a JSON file."""
if os.path.exists(CONFIG_FILE):
with open(CONFIG_FILE, "r", encoding="utf-8") as f:
return json.load(f)
return []
def save_usernames(usernames_data):
"""Save usernames to a JSON file."""
with open(CONFIG_FILE, "w", encoding="utf-8") as f:
json.dump(usernames_data, f, ensure_ascii=False, indent=4)
Explanation:
load_usernames β Reads usernames from a JSON file if it exists.
save_usernames β Writes the current list of usernames to a JSON file.
3οΈβ£ Generating Random Usernames
We can create usernames in different styles:
def generate_username(length=8, style="Normal"):
"""Generate username based on selected style."""
if style == "Normal":
chars = string.ascii_letters + string.digits
elif style == "Lowercase":
chars = string.ascii_lowercase + string.digits
elif style == "Uppercase":
chars = string.ascii_uppercase + string.digits
elif style == "NumberEnd":
name = ''.join(random.choice(string.ascii_letters) for _ in range(length-1))
return name + random.choice(string.digits)
else:
chars = string.ascii_letters + string.digits
return ''.join(random.choice(chars) for _ in range(length))
Explanation:
Normal β Letters + numbers.
Lowercase β Only lowercase letters + numbers.
Uppercase β Only uppercase letters + numbers.
NumberEnd β Ends with a number.
4οΈβ£ Setting Up the Main Window
Now we create the main GUI window:
root = tk.Tk()
root.title("π² Random Username Generator Pro")
root.geometry("970x600")
sv_ttk.set_theme("light") # Optional: modern theme
Explanation:
root.title β Sets the window title.
root.geometry β Sets the window size.
sv_ttk.set_theme β Makes the GUI look modern.
5οΈβ£ Global Variables
We store the data and user selections in global variables:
usernames_data = load_usernames()
filtered_usernames = usernames_data.copy()
current_filter = tk.StringVar(value="")
current_sort = tk.StringVar(value="Alphabetical")
current_style = tk.StringVar(value="Normal")
Explanation:
usernames_data β All usernames.
filtered_usernames β Displayed usernames after filtering.
current_filter β Tracks the filter text.
current_sort β Tracks the selected sorting method.
current_style β Tracks the username style.
6οΈβ£ Adding Username Functions
We need functions for generate, clear, copy, filter, and sort:
Generate in a thread
def add_username_thread(length, count, style):
"""Generate usernames without freezing GUI."""
def task():
global usernames_data
for _ in range(count):
usernames_data.append(generate_username(length, style))
save_usernames(usernames_data)
apply_filter_sort()
set_status(f"Generated {count} username(s).")
Thread(target=task, daemon=True).start()
Explanation:
Runs username generation in a background thread.
Keeps the GUI responsive.
Other functions
def clear_usernames():
if messagebox.askyesno("Confirm", "Clear all saved usernames?"):
usernames_data.clear()
apply_filter_sort()
save_usernames(usernames_data)
set_status("All usernames cleared.")
def copy_selected(event=None):
try:
value = username_text.get("sel.first", "sel.last")
root.clipboard_clear()
root.clipboard_append(value)
set_status(f"Copied '{value}' to clipboard.")
except tk.TclError:
set_status("No selection to copy.")
Explanation:
clear_usernames β Deletes all usernames after confirmation.
copy_selected β Copies highlighted text to clipboard.
Filter & Sort
def apply_filter_sort(*args):
global filtered_usernames
filter_text = current_filter.get().lower()
filtered_usernames = [u for u in usernames_data if filter_text in u.lower()] if filter_text else usernames_data.copy()
# Sorting options
if current_sort.get() == "Alphabetical":
filtered_usernames.sort()
elif current_sort.get() == "Length (Short β Long)":
filtered_usernames.sort(key=len)
elif current_sort.get() == "Length (Long β Short)":
filtered_usernames.sort(key=len, reverse=True)
update_username_text(filter_text)
Explanation:
Filters usernames based on input.
Sorts by alphabetical or length.
7οΈβ£ Setting Up the GUI Layout
Weβll create the frames, inputs, and buttons:
main_frame = ttk.Frame(root, padding=20)
main_frame.pack(expand=True, fill="both")
ttk.Label(main_frame, text="π² Random Username Generator Pro", font=("Segoe UI", 22, "bold")).pack(pady=(0,10))
Input frame
input_frame = ttk.LabelFrame(main_frame, text="Settings", padding=10)
input_frame.pack(fill="x", pady=5)
ttk.Label(input_frame, text="Length:").grid(row=0, column=0)
length_entry = ttk.Entry(input_frame, width=10)
length_entry.grid(row=0, column=1)
length_entry.insert(0, "8")
ttk.Label(input_frame, text="Count:").grid(row=0, column=2)
count_entry = ttk.Entry(input_frame, width=10)
count_entry.grid(row=0, column=3)
count_entry.insert(0, "10")
ttk.Label(input_frame, text="Style:").grid(row=0, column=4)
style_combo = ttk.Combobox(input_frame, state="readonly", textvariable=current_style, width=20)
style_combo['values'] = ["Normal", "Lowercase", "Uppercase", "NumberEnd"]
style_combo.grid(row=0, column=5)
Explanation:
ttk.Frame β Organizes the layout.
ttk.Entry β Input fields for length and count.
ttk.Combobox β Dropdown for username style.
Buttons
ttk.Button(input_frame, text="Generate", command=generate_usernames).grid(row=0, column=6, padx=5)
ttk.Button(input_frame, text="Clear All", command=clear_usernames).grid(row=0, column=7, padx=5)
ttk.Button(input_frame, text="Copy Selected", command=copy_selected).grid(row=0, column=8, padx=5)
Explanation:
Generate β Calls function to create usernames.
Clear All β Deletes all usernames.
Copy Selected β Copies highlighted text.
8οΈβ£ Display Area with Scrollbar
text_frame = ttk.Frame(main_frame)
text_frame.pack(expand=True, fill="both", pady=10)
username_text = tk.Text(text_frame, font=("Segoe UI", 12), state=tk.DISABLED, wrap="none", height=10)
username_text.pack(side="left", expand=True, fill="both")
scrollbar = ttk.Scrollbar(text_frame, orient="vertical", command=username_text.yview)
scrollbar.pack(side="right", fill="y")
username_text.config(yscrollcommand=scrollbar.set)
username_text.bind("<Control-c>", copy_selected)
Explanation:
tk.Text β Displays usernames.
Scrollbar β Allows scrolling through many usernames.
9οΈβ£ Status Bar & Total Count
total_var = tk.StringVar(value=f"Total Usernames: {len(filtered_usernames)}")
ttk.Label(main_frame, textvariable=total_var, font=("Segoe UI", 12)).pack()
status_var = tk.StringVar(value="Ready")
ttk.Label(root, textvariable=status_var, anchor="w").pack(side="bottom", fill="x")
Explanation:
Shows total usernames and status messages like βCopiedβ or βGeneratedβ.
10οΈβ£ Run the App
Finally, initialize and run the app:
apply_filter_sort() # Load existing usernames
root.mainloop() # Start GUI loop
Congratulations! π
You now have a fully functional Random Username Generator in Python with filtering, sorting, and threading support.

Top comments (0)