🎲 Build a Random Username Generator in Python with Tkinter

Published: (February 10, 2026 at 11:38 PM EST)
7 min read
Source: Dev.to

Source: Dev.to

🎲 Random Username Generator – Tutorial

In this tutorial we’ll build a Random Username Generator using Python, Tkinter, and threading. The app lets users 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

  1. Create a new Python file called username_generator.py.
  2. Make sure you have Python 3.9+ installed.

Imports

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

ModulePurpose
os & jsonSave and load usernames from a file.
random & stringGenerate random usernames.
tkinterMain GUI toolkit.
sv_ttkModern light/dark theme for Tkinter.
ThreadRun username generation without freezing the GUI.

2️⃣ Helper Functions

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

def generate_username(length=8, style="Normal"):
    """Generate a username based on the 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

StyleDescription
NormalLetters (both cases) + numbers
LowercaseOnly lowercase letters + numbers
UppercaseOnly uppercase letters + numbers
NumberEndEnds with a number

4️⃣ Setting Up the Main Window

root = tk.Tk()
root.title("🎲 Random Username Generator Pro")
root.geometry("970x600")
sv_ttk.set_theme("light")   # Optional: modern theme
  • root.title – Sets the window title.
  • root.geometry – Sets the window size.
  • sv_ttk.set_theme – Gives the GUI a modern look.

5️⃣ 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")
  • usernames_data – All usernames (saved + generated).
  • filtered_usernames – Usernames displayed 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

Generate in a Thread

def add_username_thread(length, count, style):
    """Generate usernames without freezing the 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()

Runs username generation in a background thread, keeping 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.")
  • clear_usernames – Deletes all usernames after confirmation.
  • copy_selected – Copies highlighted text to the clipboard.

Filter & Sort

def apply_filter_sort(*args):
    global filtered_usernames
    filter_text = current_filter.get().lower()

    # Filtering
    filtered_usernames = (
        [u for u in usernames_data if filter_text in u.lower()]
        if filter_text else usernames_data.copy()
    )

    # Sorting
    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)

Filters usernames based on the input and sorts them alphabetically or by length.


7️⃣ Setting Up the GUI Layout

# ----- Main container -------------------------------------------------
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))

# ----- Settings frame --------------------------------------------------
input_frame = ttk.LabelFrame(main_frame, text="Settings", padding=10)
input_frame.pack(fill="x", pady=5)

# Length
ttk.Label(input_frame, text="Length:").grid(row=0, column=0, sticky="w")
length_entry = ttk.Entry(input_frame, width=10)
length_entry.grid(row=0, column=1, padx=5)
length_entry.insert(0, "8")

# Count
ttk.Label(input_frame, text="Count:").grid(row=0, column=2, sticky="w")
count_entry = ttk.Entry(input_frame, width=10)
count_entry.grid(row=0, column=3, padx=5)
count_entry.insert(0, "10")

# Style (dropdown)
ttk.Label(input_frame, text="Style:").grid(row=0, column=4, sticky="w")
style_combo = ttk.Combobox(
    input_frame,
    textvariable=current_style,
    values=["Normal", "Lowercase", "Uppercase", "NumberEnd"],
    state="readonly",
    width=12
)
style_combo.grid(row=0, column=5, padx=5)
style_combo.current(0)

# ----- Buttons ---------------------------------------------------------
button_frame = ttk.Frame(main_frame, padding=(0, 10))
button_frame.pack(fill="x")

generate_btn = ttk.Button(
    button_frame,
    text="Generate",
    command=lambda: add_username_thread(
        int(length_entry.get()),
        int(count_entry.get()),
        current_style.get()
    )
)
generate_btn.pack(side="left", padx=5)

clear_btn = ttk.Button(button_frame, text="Clear All", command=clear_usernames)
clear_btn.pack(side="left", padx=5)

copy_btn = ttk.Button(button_frame, text="Copy Selected", command=copy_selected)
copy_btn.pack(side="left", padx=5)

# ----- Username display (scrollable Text widget) -----------------------
display_frame = ttk.LabelFrame(main_frame, text="Usernames", padding=10)
display_frame.pack(expand=True, fill="both", pady=5)

username_text = tk.Text(display_frame, wrap="none", height=15)
username_text.pack(side="left", expand=True, fill="both")

scroll_y = ttk.Scrollbar(display_frame, orient="vertical", command=username_text.yview)
scroll_y.pack(side="right", fill="y")
username_text.configure(yscrollcommand=scroll_y.set)

# ----- Filter & Sort ---------------------------------------------------
filter_frame = ttk.LabelFrame(main_frame, text="Filter / Sort", padding=10)
filter_frame.pack(fill="x", pady=5)

ttk.Label(filter_frame, text="Filter:").grid(row=0, column=0, sticky="w")
filter_entry = ttk.Entry(filter_frame, textvariable=current_filter, width=30)
filter_entry.grid(row=0, column=1, padx=5)

ttk.Label(filter_frame, text="Sort:").grid(row=0, column=2, sticky="w")
sort_combo = ttk.Combobox(
    filter_frame,
    textvariable=current_sort,
    values=["Alphabetical", "Length (Short → Long)", "Length (Long → Short)"],
    state="readonly",
    width=20
)
sort_combo.grid(row=0, column=3, padx=5)
sort_combo.current(0)

# Bind filter/sort changes
current_filter.trace_add("write", apply_filter_sort)
current_sort.trace_add("write", apply_filter_sort)

# ----- Status bar -------------------------------------------------------
status_var = tk.StringVar(value="Ready.")
status_bar = ttk.Label(root, textvariable=status_var, relief="sunken", anchor="w")
status_bar.pack(fill="x", side="bottom")

def set_status(message: str):
    status_var.set(message)
    root.after(3000, lambda: status_var.set("Ready."))

The layout consists of:

  • Settings – Length, Count, and Style.
  • Buttons – Generate, Clear All, Copy Selected.
  • Usernames – Scrollable Text widget showing generated usernames.
  • Filter / Sort – Live filter entry and sort dropdown.
  • Status bar – Shows short messages (e.g., “Generated 10 username(s)”).

8️⃣ Run the Application

if __name__ == "__main__":
    apply_filter_sort()   # Populate the display on start
    root.mainloop()

That’s it! You now have a fully functional Random Username Generator with a modern UI, background processing, filtering, sorting, and clipboard support. Feel free to experiment with additional styles or export options. Happy coding!

1️⃣ Imports & Setup

import tkinter as tk
from tkinter import ttk
import random
import string

2️⃣ Helper Functions

def generate_usernames():
    # Your generation logic here
    ...

def clear_usernames():
    # Clear the text widget
    ...

def copy_selected(event=None):
    # Copy selected text to clipboard
    ...

def apply_filter_sort():
    # Filter and sort usernames
    ...

3️⃣ Main Window

root = tk.Tk()
root.title("Username Generator")
root.geometry("800x600")

4️⃣ Main Frame

main_frame = ttk.Frame(root, padding=10)
main_frame.pack(expand=True, fill="both")

5️⃣ Input Section

input_frame = ttk.Frame(main_frame)
input_frame.pack(fill="x", pady=5)

# Length
ttk.Label(input_frame, text="Length:").grid(row=0, column=0, sticky="e")
length_var = tk.IntVar(value=8)
ttk.Entry(input_frame, textvariable=length_var, width=5).grid(row=0, column=1)

# Count
ttk.Label(input_frame, text="Count:").grid(row=0, column=2, sticky="e")
count_var = tk.IntVar(value=10)
ttk.Entry(input_frame, textvariable=count_var, width=5).grid(row=0, column=3)

# Style
ttk.Label(input_frame, text="Style:").grid(row=0, column=4)
current_style = tk.StringVar(value="Normal")
style_combo = ttk.Combobox(
    input_frame,
    state="readonly",
    textvariable=current_style,
    width=20,
    values=["Normal", "Lowercase", "Uppercase", "NumberEnd"]
)
style_combo.grid(row=0, column=5)

Explanation

WidgetPurpose
ttk.FrameOrganises the layout.
ttk.EntryInput fields for length and count.
ttk.ComboboxDropdown for username style.

6️⃣ 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

ButtonAction
GenerateCalls generate_usernames to create usernames.
Clear AllDeletes all usernames from the display.
Copy SelectedCopies highlighted text to the clipboard.

7️⃣ 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("", copy_selected)

Explanation

ComponentPurpose
tk.TextDisplays generated usernames.
ttk.ScrollbarAllows scrolling through many usernames.

8️⃣ 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 the total number of usernames and status messages such as “Copied” or “Generated”.


9️⃣ Run the App

apply_filter_sort()   # Load existing usernames (if any)
root.mainloop()       # Start the GUI event loop

Congratulations! 🎉 Your username generator GUI is now ready to use.

0 views
Back to Blog

Related posts

Read more »