|
| 1 | +import tkinter as tk |
| 2 | +from tkinter import filedialog, messagebox |
| 3 | +import random |
| 4 | +import os |
| 5 | + |
| 6 | +class RandomNamePickerApp: |
| 7 | + def __init__(self, root): |
| 8 | + self.root = root |
| 9 | + self.root.title("Random Name Picker") |
| 10 | + self.root.geometry("700x750") |
| 11 | + self.root.configure(bg="#1f2f3a") |
| 12 | + self.root.resizable(False, False) |
| 13 | + |
| 14 | + self.names = [] |
| 15 | + self.file_path = None |
| 16 | + |
| 17 | + self.create_ui() |
| 18 | + |
| 19 | + def create_ui(self): |
| 20 | + # Title |
| 21 | + tk.Label(self.root, text="Random Name Picker", font=("Helvetica", 28, "bold"), |
| 22 | + bg="#1f2f3a", fg="#ffffff").pack(pady=20) |
| 23 | + |
| 24 | + # Input frame |
| 25 | + input_frame = tk.Frame(self.root, bg="#1f2f3a") |
| 26 | + input_frame.pack(pady=10, fill="x", padx=20) |
| 27 | + |
| 28 | + tk.Label(input_frame, text="Enter Name:", font=("Helvetica", 12), |
| 29 | + bg="#1f2f3a", fg="#bdc3c7").grid(row=0, column=0, sticky="w") |
| 30 | + self.name_entry = tk.Entry(input_frame, font=("Helvetica", 12), bd=0, |
| 31 | + highlightthickness=2, highlightbackground="#27ae60", width=30) |
| 32 | + self.name_entry.grid(row=0, column=1, pady=5, padx=5, ipady=12) |
| 33 | + |
| 34 | + tk.Button(input_frame, text="Add Name", command=self.add_name, |
| 35 | + bg="#2980b9", fg="white", font=("Helvetica", 12, "bold"), |
| 36 | + width=12, height=2, bd=0, activebackground="#3498db", cursor="hand2").grid(row=0, column=2, padx=5) |
| 37 | + |
| 38 | + # Names listbox |
| 39 | + list_frame = tk.Frame(self.root, bg="#1f2f3a") |
| 40 | + list_frame.pack(pady=10, fill="both", expand=True, padx=20) |
| 41 | + tk.Label(list_frame, text="Names List:", font=("Helvetica", 12), bg="#1f2f3a", fg="#bdc3c7").pack(anchor="w") |
| 42 | + |
| 43 | + self.listbox = tk.Listbox(list_frame, font=("Helvetica", 12), bg="#2c3e50", |
| 44 | + fg="white", selectbackground="#2980b9", selectforeground="white") |
| 45 | + self.listbox.pack(fill="both", expand=True, pady=5) |
| 46 | + scrollbar = tk.Scrollbar(self.listbox, orient="vertical") |
| 47 | + scrollbar.pack(side="right", fill="y") |
| 48 | + self.listbox.config(yscrollcommand=scrollbar.set) |
| 49 | + scrollbar.config(command=self.listbox.yview) |
| 50 | + |
| 51 | + # Buttons frame |
| 52 | + btn_frame = tk.Frame(self.root, bg="#1f2f3a") |
| 53 | + btn_frame.pack(pady=10) |
| 54 | + |
| 55 | + tk.Button(btn_frame, text="Pick Random Name", command=self.pick_random_name, |
| 56 | + bg="#27ae60", fg="white", font=("Helvetica", 12, "bold"), |
| 57 | + width=20, height=2, bd=0, activebackground="#2ecc71", cursor="hand2").grid(row=0, column=0, padx=10, pady=5) |
| 58 | + |
| 59 | + tk.Button(btn_frame, text="Pick Multiple Names", command=self.pick_multiple_names, |
| 60 | + bg="#2980b9", fg="white", font=("Helvetica", 12, "bold"), |
| 61 | + width=20, height=2, bd=0, activebackground="#3498db", cursor="hand2").grid(row=0, column=1, padx=10, pady=5) |
| 62 | + |
| 63 | + tk.Button(btn_frame, text="Remove Selected", command=self.remove_selected, |
| 64 | + bg="#e67e22", fg="white", font=("Helvetica", 12, "bold"), |
| 65 | + width=20, height=2, bd=0, activebackground="#f39c12", cursor="hand2").grid(row=1, column=0, padx=10, pady=5) |
| 66 | + |
| 67 | + tk.Button(btn_frame, text="Clear All", command=self.clear_all, |
| 68 | + bg="#c0392b", fg="white", font=("Helvetica", 12, "bold"), |
| 69 | + width=20, height=2, bd=0, activebackground="#e74c3c", cursor="hand2").grid(row=1, column=1, padx=10, pady=5) |
| 70 | + |
| 71 | + # File operations frame |
| 72 | + file_frame = tk.Frame(self.root, bg="#1f2f3a") |
| 73 | + file_frame.pack(pady=10) |
| 74 | + |
| 75 | + tk.Button(file_frame, text="Load Names from File", command=self.load_from_file, |
| 76 | + bg="#8e44ad", fg="white", font=("Helvetica", 12, "bold"), |
| 77 | + width=25, height=2, bd=0, activebackground="#9b59b6", cursor="hand2").grid(row=0, column=0, padx=10, pady=5) |
| 78 | + |
| 79 | + tk.Button(file_frame, text="Save Names to File", command=self.save_to_file, |
| 80 | + bg="#16a085", fg="white", font=("Helvetica", 12, "bold"), |
| 81 | + width=25, height=2, bd=0, activebackground="#1abc9c", cursor="hand2").grid(row=0, column=1, padx=10, pady=5) |
| 82 | + |
| 83 | + # Remove winners option |
| 84 | + option_frame = tk.Frame(self.root, bg="#1f2f3a") |
| 85 | + option_frame.pack(pady=5) |
| 86 | + self.remove_var = tk.IntVar() |
| 87 | + tk.Checkbutton(option_frame, text="Remove winners after picking", variable=self.remove_var, |
| 88 | + font=("Helvetica", 12), bg="#1f2f3a", fg="#bdc3c7", activebackground="#1f2f3a", |
| 89 | + selectcolor="#2980b9").pack(anchor="w", padx=20) |
| 90 | + |
| 91 | + # --- Core Functionalities --- |
| 92 | + def add_name(self): |
| 93 | + name = self.name_entry.get().strip() |
| 94 | + if name: |
| 95 | + self.names.append(name) |
| 96 | + self.update_listbox() |
| 97 | + self.name_entry.delete(0, tk.END) |
| 98 | + else: |
| 99 | + messagebox.showerror("Error", "Please enter a name.") |
| 100 | + |
| 101 | + def update_listbox(self): |
| 102 | + self.listbox.delete(0, tk.END) |
| 103 | + for name in self.names: |
| 104 | + self.listbox.insert(tk.END, name) |
| 105 | + |
| 106 | + def pick_random_name(self): |
| 107 | + if not self.names: |
| 108 | + messagebox.showerror("Error", "No names to pick from!") |
| 109 | + return |
| 110 | + winner = random.choice(self.names) |
| 111 | + messagebox.showinfo("Winner", f"The selected name is:\n\n{winner}") |
| 112 | + if self.remove_var.get(): |
| 113 | + self.names.remove(winner) |
| 114 | + self.update_listbox() |
| 115 | + |
| 116 | + def pick_multiple_names(self): |
| 117 | + if not self.names: |
| 118 | + messagebox.showerror("Error", "No names to pick from!") |
| 119 | + return |
| 120 | + |
| 121 | + # Ask for number of winners |
| 122 | + num_window = tk.Toplevel(self.root) |
| 123 | + num_window.title("Number of Winners") |
| 124 | + num_window.geometry("300x150") |
| 125 | + num_window.configure(bg="#1f2f3a") |
| 126 | + tk.Label(num_window, text="Enter number of winners:", font=("Helvetica", 12), |
| 127 | + bg="#1f2f3a", fg="#bdc3c7").pack(pady=20) |
| 128 | + num_entry = tk.Entry(num_window, font=("Helvetica", 12), bd=0, |
| 129 | + highlightthickness=2, highlightbackground="#27ae60", width=10) |
| 130 | + num_entry.pack(pady=5) |
| 131 | + |
| 132 | + def pick_winners(): |
| 133 | + try: |
| 134 | + n = int(num_entry.get()) |
| 135 | + if n <= 0: |
| 136 | + raise ValueError |
| 137 | + if n > len(self.names): |
| 138 | + messagebox.showerror("Error", f"Cannot pick {n} names from {len(self.names)} available!") |
| 139 | + return |
| 140 | + winners = random.sample(self.names, n) |
| 141 | + messagebox.showinfo("Winners", "The selected winners are:\n\n" + "\n".join(winners)) |
| 142 | + if self.remove_var.get(): |
| 143 | + for winner in winners: |
| 144 | + self.names.remove(winner) |
| 145 | + self.update_listbox() |
| 146 | + num_window.destroy() |
| 147 | + except ValueError: |
| 148 | + messagebox.showerror("Error", "Please enter a valid positive integer.") |
| 149 | + |
| 150 | + tk.Button(num_window, text="Pick", command=pick_winners, |
| 151 | + bg="#27ae60", fg="white", font=("Helvetica", 12, "bold"), |
| 152 | + width=10, height=2, bd=0, activebackground="#2ecc71", cursor="hand2").pack(pady=10) |
| 153 | + |
| 154 | + def remove_selected(self): |
| 155 | + selected = self.listbox.curselection() |
| 156 | + if not selected: |
| 157 | + messagebox.showerror("Error", "No name selected!") |
| 158 | + return |
| 159 | + for index in reversed(selected): |
| 160 | + del self.names[index] |
| 161 | + self.update_listbox() |
| 162 | + |
| 163 | + def clear_all(self): |
| 164 | + confirm = messagebox.askyesno("Confirm", "Are you sure you want to clear all names?") |
| 165 | + if confirm: |
| 166 | + self.names = [] |
| 167 | + self.update_listbox() |
| 168 | + |
| 169 | + # --- File Operations --- |
| 170 | + def load_from_file(self): |
| 171 | + path = filedialog.askopenfilename(title="Select file", filetypes=[("Text Files", "*.txt")]) |
| 172 | + if path: |
| 173 | + try: |
| 174 | + with open(path, "r", encoding="utf-8") as f: |
| 175 | + loaded_names = [line.strip() for line in f.readlines() if line.strip()] |
| 176 | + if loaded_names: |
| 177 | + self.names.extend(loaded_names) |
| 178 | + self.update_listbox() |
| 179 | + self.file_path = path |
| 180 | + messagebox.showinfo("Success", f"Loaded {len(loaded_names)} names from file.") |
| 181 | + else: |
| 182 | + messagebox.showwarning("Warning", "The file is empty.") |
| 183 | + except Exception as e: |
| 184 | + messagebox.showerror("Error", f"Failed to load file: {e}") |
| 185 | + |
| 186 | + def save_to_file(self): |
| 187 | + if not self.names: |
| 188 | + messagebox.showerror("Error", "No names to save!") |
| 189 | + return |
| 190 | + |
| 191 | + if self.file_path: |
| 192 | + save_path = self.file_path |
| 193 | + else: |
| 194 | + save_path = filedialog.asksaveasfilename(defaultextension=".txt", filetypes=[("Text Files", "*.txt")]) |
| 195 | + if not save_path: |
| 196 | + return |
| 197 | + |
| 198 | + try: |
| 199 | + with open(save_path, "w", encoding="utf-8") as f: |
| 200 | + for name in self.names: |
| 201 | + f.write(name + "\n") |
| 202 | + messagebox.showinfo("Success", f"Saved {len(self.names)} names to file.") |
| 203 | + self.file_path = save_path |
| 204 | + except Exception as e: |
| 205 | + messagebox.showerror("Error", f"Failed to save file: {e}") |
| 206 | + |
| 207 | + |
| 208 | +if __name__ == "__main__": |
| 209 | + root = tk.Tk() |
| 210 | + app = RandomNamePickerApp(root) |
| 211 | + root.mainloop() |
0 commit comments