- Update project SDK to Python 3.13.

- Refactor main.py for improved readability, type-hinting, and UI enhancements using `ttk` widgets.
- Adjust `.idea` configuration for compatibility with updated SDK.
This commit is contained in:
2026-01-14 13:27:38 +01:00
parent e3c2b60c4f
commit 791070600f
3 changed files with 73 additions and 56 deletions
+1 -1
View File
@@ -4,7 +4,7 @@
<content url="file://$MODULE_DIR$"> <content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.venv" /> <excludeFolder url="file://$MODULE_DIR$/.venv" />
</content> </content>
<orderEntry type="jdk" jdkName="Python 3.11 (Autoclicker)" jdkType="Python SDK" /> <orderEntry type="jdk" jdkName="Python 3.13" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
</component> </component>
</module> </module>
+1
View File
@@ -3,4 +3,5 @@
<component name="Black"> <component name="Black">
<option name="sdkName" value="Python 3.11 (Autoclicker)" /> <option name="sdkName" value="Python 3.11 (Autoclicker)" />
</component> </component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.13" project-jdk-type="Python SDK" />
</project> </project>
+70 -54
View File
@@ -1,110 +1,126 @@
import tkinter as tk import tkinter as tk
from tkinter import DISABLED, NORMAL from tkinter import DISABLED, NORMAL
from tkinter import ttk
from pynput.mouse import Controller, Button from pynput.mouse import Controller, Button
from pynput.keyboard import Listener, KeyCode from pynput.keyboard import Listener, KeyCode
import threading import threading
import time import time
mouse = Controller() mouse = Controller()
clicking = False clicking = False
HOTKEY = KeyCode(char='-') HOTKEY = KeyCode(char='-')
def click_loop(delay): def click_loop(delay: float) -> None:
"""Continuously clicks while clicking is True.""" """Continuously click the left mouse button while ``clicking`` is True.
Args:
delay: The number of seconds to wait between clicks.
"""
global clicking global clicking
while clicking: while clicking:
mouse.click(Button.left, 1) mouse.click(Button.left, 1)
time.sleep(delay) time.sleep(delay)
def toggle_clicking(): def toggle_clicking() -> None:
"""Toggles the clicking state.""" """Toggle the clicking state and start or stop the click thread as needed."""
global clicking global clicking
clicking = not clicking clicking = not clicking
if clicking: if clicking:
try: try:
delay = float(delay_entry.get()) delay_val = float(delay_var.get())
except ValueError: except ValueError:
delay = 0.5 delay_val = 0.5
thread = threading.Thread(target=click_loop, args=(delay,)) thread = threading.Thread(target=click_loop, args=(delay_val,))
thread.daemon = True thread.daemon = True
thread.start() thread.start()
start_button.focus_set()
root.focus_set() root.focus_set()
switch() switch_buttons()
def switch(): def switch_buttons() -> None:
"""Update button states based on whether clicking is active."""
if clicking: if clicking:
start_button["state"] = DISABLED start_button.config(state=DISABLED)
stop_button["state"] = NORMAL stop_button.config(state=NORMAL)
else: else:
start_button["state"] = NORMAL start_button.config(state=NORMAL)
stop_button["state"] = DISABLED stop_button.config(state=DISABLED)
def on_key_press(key): def on_key_press(key) -> None:
"""Handles keypress events to toggle clicking.""" """Handle keypress events to toggle clicking when the hotkey is pressed."""
if key == HOTKEY: if key == HOTKEY:
toggle_clicking() toggle_clicking()
def clear_focus(event): def clear_focus(event) -> None:
"""Clears focus from entry when clicking anywhere else, """Clear focus from entry widgets when clicking elsewhere in the window."""
except if clicking on an entry widget."""
if event.widget not in (delay_entry, hotkey_entry): if event.widget not in (delay_entry, hotkey_entry):
root.focus_set() root.focus_set()
def open_config(): def open_config() -> None:
"""Opens the configuration menu by hiding the main frame and showing the config frame.""" """Display the configuration frame and hide the main frame."""
main_frame.pack_forget() main_frame.grid_remove()
config_frame.pack(fill=tk.BOTH, expand=True) config_frame.grid(row=0, column=0, sticky="NSEW")
def close_config(): def close_config() -> None:
"""Closes the configuration menu, updates HOTKEY, and returns to the main UI.""" """Hide the configuration frame, update the hotkey, and show the main frame."""
global HOTKEY global HOTKEY
new_hotkey = hotkey_entry.get().strip() new_hotkey = hotkey_entry.get().strip()
if new_hotkey: if new_hotkey:
HOTKEY = KeyCode(char=new_hotkey[0]) HOTKEY = KeyCode(char=new_hotkey[0])
start_button.config(text=f"Start ({HOTKEY.char.upper()})") start_button.config(text=f"Start ({HOTKEY.char.upper()})")
stop_button.config(text=f"Stop ({HOTKEY.char.upper()})") stop_button.config(text=f"Stop ({HOTKEY.char.upper()})")
main_hotkey_label.config(text=f"Press '{HOTKEY.char}' to Start/Stop") main_hotkey_label.config(text=f"Press '{HOTKEY.char.upper()}' to Start/Stop")
config_frame.pack_forget() config_frame.grid_remove()
main_frame.pack(fill=tk.BOTH, expand=True) main_frame.grid()
root = tk.Tk() root = tk.Tk()
root.title("Fretux' Autoclicker") root.title("Fretux' Autoclicker")
root.geometry("300x200") root.geometry("350x250")
root.eval('tk::PlaceWindow . center') root.resizable(False, False)
main_frame = tk.Frame(root) style = ttk.Style(root)
main_frame.pack(fill=tk.BOTH, expand=True) try:
tk.Label(main_frame, text="Delay between clicks (seconds):").pack(pady=5) style.theme_use('clam')
delay_entry = tk.Entry(main_frame) except tk.TclError:
delay_entry.pack(pady=5) style.theme_use(style.theme_names()[0])
delay_entry.insert(0, "0.5") style.configure("TButton", padding=6)
main_hotkey_label = tk.Label(main_frame, text=f"Press '{HOTKEY.char}' to Start/Stop") style.configure("TEntry", padding=3)
main_hotkey_label.pack(pady=5) style.configure("TLabel", padding=3)
button_frame = tk.Frame(main_frame) root.columnconfigure(0, weight=1)
button_frame.pack(pady=10) root.rowconfigure(0, weight=1)
start_button = tk.Button(button_frame, text=f"Start ({HOTKEY.char.upper()})", command=toggle_clicking, width=15) main_frame = ttk.Frame(root, padding=10)
stop_button = tk.Button(button_frame, text=f"Stop ({HOTKEY.char.upper()})", command=toggle_clicking, width=15) main_frame.grid(row=0, column=0, sticky="NSEW")
start_button.pack(side=tk.LEFT, padx=5) delay_label = ttk.Label(main_frame, text="Delay between clicks (seconds):")
stop_button.pack(side=tk.LEFT, padx=5) delay_label.grid(row=0, column=0, sticky="W", padx=(0, 5), pady=(0, 5))
config_button = tk.Button(main_frame, text="Configure", command=open_config) delay_var = tk.StringVar(value="0.5")
config_button.pack(pady=5) delay_entry = ttk.Entry(main_frame, textvariable=delay_var, width=10)
config_frame = tk.Frame(root) delay_entry.grid(row=0, column=1, sticky="W", pady=(0, 5))
tk.Label(config_frame, text="Configure HOTKEY").pack(pady=10) main_hotkey_label = ttk.Label(main_frame, text=f"Press '{HOTKEY.char.upper()}' to Start/Stop")
hotkey_entry = tk.Entry(config_frame) main_hotkey_label.grid(row=1, column=0, columnspan=2, sticky="W", pady=(0, 10))
hotkey_entry.pack(pady=5) 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.insert(0, HOTKEY.char)
back_button = tk.Button(config_frame, text="Back", command=close_config) hotkey_entry.grid(row=1, column=0, sticky="W", pady=(0, 10))
back_button.pack(pady=10) back_button = ttk.Button(config_frame, text="Back", command=close_config)
back_button.grid(row=2, column=0, sticky="W")
root.bind("<Button-1>", clear_focus) root.bind("<Button-1>", clear_focus)
listener = Listener(on_press=on_key_press) listener = Listener(on_press=on_key_press)
listener.start() listener.start()
stop_button["state"] = DISABLED stop_button.config(state=DISABLED)
root.mainloop() root.mainloop()