import tkinter as tk from tkinter import DISABLED, NORMAL from tkinter import ttk from pynput.mouse import Controller, Button from pynput.keyboard import Listener, KeyCode import threading import time mouse = Controller() clicking = False HOTKEY = KeyCode(char='-') def click_loop(delay: float) -> None: """Continuously click the left mouse button while ``clicking`` is True. Args: delay: The number of seconds to wait between clicks. """ global clicking while clicking: mouse.click(Button.left, 1) time.sleep(delay) def toggle_clicking() -> None: """Toggle the clicking state and start or stop the click thread as needed.""" global clicking clicking = not clicking if clicking: try: delay_val = float(delay_var.get()) except ValueError: delay_val = 0.5 thread = threading.Thread(target=click_loop, args=(delay_val,)) thread.daemon = True thread.start() root.focus_set() switch_buttons() def switch_buttons() -> None: """Update button states based on whether clicking is active.""" if clicking: start_button.config(state=DISABLED) stop_button.config(state=NORMAL) else: start_button.config(state=NORMAL) stop_button.config(state=DISABLED) def on_key_press(key) -> None: """Handle keypress events to toggle clicking when the hotkey is pressed.""" if key == HOTKEY: toggle_clicking() def clear_focus(event) -> None: """Clear focus from entry widgets when clicking elsewhere in the window.""" if event.widget not in (delay_entry, hotkey_entry): root.focus_set() def open_config() -> None: """Display the configuration frame and hide the main frame.""" main_frame.grid_remove() config_frame.grid(row=0, column=0, sticky="NSEW") def close_config() -> None: """Hide the configuration frame, update the hotkey, and show the main frame.""" global HOTKEY new_hotkey = hotkey_entry.get().strip() if new_hotkey: HOTKEY = KeyCode(char=new_hotkey[0]) start_button.config(text=f"Start ({HOTKEY.char.upper()})") stop_button.config(text=f"Stop ({HOTKEY.char.upper()})") main_hotkey_label.config(text=f"Press '{HOTKEY.char.upper()}' to Start/Stop") config_frame.grid_remove() main_frame.grid() root = tk.Tk() root.title("Fretux' Autoclicker") root.geometry("350x250") root.resizable(False, False) style = ttk.Style(root) try: style.theme_use('clam') except tk.TclError: style.theme_use(style.theme_names()[0]) style.configure("TButton", padding=6) style.configure("TEntry", padding=3) style.configure("TLabel", padding=3) root.columnconfigure(0, weight=1) root.rowconfigure(0, weight=1) main_frame = ttk.Frame(root, padding=10) main_frame.grid(row=0, column=0, sticky="NSEW") delay_label = ttk.Label(main_frame, text="Delay between clicks (seconds):") delay_label.grid(row=0, column=0, sticky="W", padx=(0, 5), pady=(0, 5)) delay_var = tk.StringVar(value="0.5") delay_entry = ttk.Entry(main_frame, textvariable=delay_var, width=10) delay_entry.grid(row=0, column=1, sticky="W", pady=(0, 5)) main_hotkey_label = ttk.Label(main_frame, text=f"Press '{HOTKEY.char.upper()}' to Start/Stop") main_hotkey_label.grid(row=1, column=0, columnspan=2, sticky="W", pady=(0, 10)) buttons_frame = ttk.Frame(main_frame) buttons_frame.grid(row=2, column=0, columnspan=2, pady=(0, 10)) start_button = ttk.Button(buttons_frame, text=f"Start ({HOTKEY.char.upper()})", command=toggle_clicking) stop_button = ttk.Button(buttons_frame, text=f"Stop ({HOTKEY.char.upper()})", command=toggle_clicking) start_button.grid(row=0, column=0, padx=(0, 5)) stop_button.grid(row=0, column=1, padx=(5, 0)) config_button = ttk.Button(main_frame, text="Configure", command=open_config) config_button.grid(row=3, column=0, columnspan=2) config_frame = ttk.Frame(root, padding=10) config_frame.columnconfigure(0, weight=1) config_label = ttk.Label(config_frame, text="Configure HOTKEY") config_label.grid(row=0, column=0, sticky="W", pady=(0, 10)) hotkey_entry = ttk.Entry(config_frame, width=10) hotkey_entry.insert(0, HOTKEY.char) hotkey_entry.grid(row=1, column=0, sticky="W", pady=(0, 10)) back_button = ttk.Button(config_frame, text="Back", command=close_config) back_button.grid(row=2, column=0, sticky="W") root.bind("", clear_focus) listener = Listener(on_press=on_key_press) listener.start() stop_button.config(state=DISABLED) root.mainloop()