Untitled
unknown
plain_text
5 months ago
14 kB
3
Indexable
import customtkinter as ctk import subprocess import threading from tkinter import StringVar class CustomKeyboard(ctk.CTkFrame): def __init__(self, master, password_var, on_connect, **kwargs): super().__init__(master, **kwargs) self.password_var = password_var self.on_connect = on_connect self.shift_mode = False # Updated layouts with modern symbols self.normal_layout = [ ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'], ['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p'], ['a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l'], ['⇧', 'z', 'x', 'c', 'v', 'b', 'n', 'm', '⌫'], ['123', 'space', '✓'] ] self.shift_layout = [ ['!', '@', '#', '$', '%', '^', '&', '*', '(', ')'], ['Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P'], ['A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L'], ['⇧', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '⌫'], ['123', 'space', '✓'] ] self.special_layout = [ ['~', '`', '"', "'", '+', '-', '_', '=', '\\', '|'], ['{', '}', '[', ']', '<', '>', ':', ';', '/', '?'], ['!', '@', '#', '$', '%', '^', '&', '*'], ['abc', '(', ')', ',', '.', '€', '£', '⌫'], ['abc', 'space', '✓'] ] self.current_layout = self.normal_layout self.create_keyboard() def create_keyboard(self): for widget in self.winfo_children(): widget.destroy() self.grid_columnconfigure(tuple(range(10)), weight=1) for row_idx, row in enumerate(self.current_layout): for col_idx, key in enumerate(row): # Modern styling configuration btn_width = 65 # Slightly smaller buttons for cleaner look btn_height = 45 corner_radius = 8 col_span = 1 # Special button configurations if key.lower() == 'space': btn_width = 350 # Wider space bar col_span = 6 display_text = ' ' elif key in ['123', 'abc']: btn_width = 90 col_span = 2 display_text = key.upper() elif key == '✓': btn_width = 90 col_span = 2 display_text = key fg_color = "#34c759" # Success green color hover_color = "#2ecc71" else: display_text = key fg_color = "#3a3a3c" # Dark gray for regular keys hover_color = "#4a4a4c" # Default colors for most buttons if key not in ['✓']: fg_color = "#3a3a3c" hover_color = "#4a4a4c" button = ctk.CTkButton( self, text=display_text, width=btn_width, height=btn_height, corner_radius=corner_radius, font=("SF Pro Display", 18), fg_color=fg_color, hover_color=hover_color, command=lambda k=key: self.key_press(k) ) # Adjust grid placement for different rows if row_idx == 2: # Center a row button.grid(row=row_idx, column=col_idx + 1, columnspan=col_span, padx=3, pady=3) else: button.grid(row=row_idx, column=col_idx, columnspan=col_span, padx=3, pady=3) def key_press(self, key): current_text = self.password_var.get() if key == '⌫': self.password_var.set(current_text[:-1]) elif key.lower() == 'space': self.password_var.set(current_text + ' ') elif key == '⇧': self.shift_mode = not self.shift_mode self.current_layout = self.shift_layout if self.shift_mode else self.normal_layout self.create_keyboard() elif key in ['123']: self.current_layout = self.special_layout self.create_keyboard() elif key == 'abc': self.current_layout = self.normal_layout self.create_keyboard() elif key == '✓': self.on_connect() else: self.password_var.set(current_text + key) class WifiConfiguratorApp(ctk.CTk): def __init__(self): super().__init__() self.title("Wi-Fi Configurator") self.geometry("1024x600") self.resizable(False, False) # Initialize variables self.networks = [] self.selected_network = StringVar() self.password = StringVar() self.show_password = ctk.BooleanVar(value=False) self.current_connection = { "SSID": "Not connected", "Signal Strength": "N/A", "IP Address": "N/A" } self.status_message = StringVar(value="Ready to connect") self.create_widgets() self.scan_wifi_networks() self.update_current_connection() def create_widgets(self): # Main container with modern styling main_container = ctk.CTkFrame(self, fg_color=("#f5f5f7", "#1c1c1e")) main_container.pack(fill="both", expand=True) # Top section container top_container = ctk.CTkFrame(main_container, fg_color="transparent") top_container.pack(fill="x", padx=20, pady=(20, 10)) # Connection status section status_frame = ctk.CTkFrame(top_container, fg_color=("#e5e5e7", "#2c2c2e")) status_frame.pack(side="left", fill="both", expand=True, padx=(0, 10)) # Status headers with modern typography title_label = ctk.CTkLabel( status_frame, text="Current Connection", font=("SF Pro Display", 24, "bold"), text_color=("black", "white") ) title_label.pack(pady=(15, 5)) self.status_label = ctk.CTkLabel( status_frame, textvariable=self.status_message, font=("SF Pro Display", 16), text_color=("#34c759", "#32d74b") ) self.status_label.pack(pady=5) # Connection details with consistent styling self.ssid_label = ctk.CTkLabel( status_frame, text="SSID: Not connected", font=("SF Pro Display", 16), text_color=("black", "white") ) self.ssid_label.pack(pady=5) self.signal_label = ctk.CTkLabel( status_frame, text="Signal Strength: N/A", font=("SF Pro Display", 16), text_color=("black", "white") ) self.signal_label.pack(pady=5) self.ip_label = ctk.CTkLabel( status_frame, text="IP Address: N/A", font=("SF Pro Display", 16), text_color=("black", "white") ) self.ip_label.pack(pady=5) # Network selection section network_frame = ctk.CTkFrame(top_container, fg_color=("#e5e5e7", "#2c2c2e")) network_frame.pack(side="right", fill="both", expand=True, padx=(10, 0)) select_label = ctk.CTkLabel( network_frame, text="Select Network", font=("SF Pro Display", 24, "bold"), text_color=("black", "white") ) select_label.pack(pady=(15, 10)) # Modern dropdown styling self.network_dropdown = ctk.CTkOptionMenu( network_frame, variable=self.selected_network, values=self.networks, width=280, height=32, font=("SF Pro Display", 16), fg_color=("#ffffff", "#3a3a3c"), button_color=("#e5e5e7", "#2c2c2e"), button_hover_color=("#d1d1d6", "#3a3a3c"), dropdown_font=("SF Pro Display", 16) ) self.network_dropdown.pack(pady=10) # Password entry container password_frame = ctk.CTkFrame(network_frame, fg_color="transparent") password_frame.pack(fill="x", padx=20, pady=5) # Modern password entry styling self.password_entry = ctk.CTkEntry( password_frame, textvariable=self.password, show="•", width=280, height=32, font=("SF Pro Display", 16), fg_color=("#ffffff", "#3a3a3c"), border_color=("#e5e5e7", "#2c2c2e") ) self.password_entry.pack(side="left", padx=(0, 5)) # Control buttons with consistent styling show_pwd_btn = ctk.CTkButton( password_frame, text="👁", width=32, height=32, font=("SF Pro Display", 16), fg_color=("#e5e5e7", "#2c2c2e"), hover_color=("#d1d1d6", "#3a3a3c"), command=self.toggle_password_visibility ) show_pwd_btn.pack(side="left", padx=2) reset_pwd_btn = ctk.CTkButton( password_frame, text="⌫", width=32, height=32, font=("SF Pro Display", 16), fg_color=("#e5e5e7", "#2c2c2e"), hover_color=("#d1d1d6", "#3a3a3c"), command=self.reset_password ) reset_pwd_btn.pack(side="left", padx=2) # Refresh button with modern styling refresh_btn = ctk.CTkButton( network_frame, text="Refresh Networks", width=280, height=32, font=("SF Pro Display", 16), fg_color=("#0a84ff", "#0a84ff"), hover_color=("#0071e3", "#0071e3"), command=self.scan_wifi_networks ) refresh_btn.pack(pady=10) # Keyboard container keyboard_frame = ctk.CTkFrame(main_container, fg_color="transparent") keyboard_frame.pack(fill="both", expand=True, padx=20, pady=20) self.keyboard = CustomKeyboard( keyboard_frame, self.password, self.start_connecting_to_wifi, fg_color="transparent" ) self.keyboard.pack(fill="both", expand=True) def scan_wifi_networks(self): self.status_message.set("Scanning for Wi-Fi networks...") self.update() try: result = subprocess.run( ["nmcli", "-t", "-f", "SSID,SIGNAL", "dev", "wifi"], capture_output=True, text=True ) if result.returncode == 0: networks = [] for line in result.stdout.split("\n"): if line and line.split(":")[0]: ssid, _ = line.split(":") if ssid and ssid not in networks: networks.append(ssid) self.networks = networks self.network_dropdown.configure(values=self.networks) if self.networks: self.selected_network.set(self.networks[0]) self.status_message.set("Wi-Fi scan completed") else: self.status_message.set("Failed to scan Wi-Fi networks") except Exception as e: self.status_message.set(f"Error: {e}") def toggle_password_visibility(self): current_show = self.password_entry.cget("show") self.password_entry.configure(show="" if current_show == "•" else "•") def reset_password(self): self.password.set("") def start_connecting_to_wifi(self): threading.Thread(target=self.connect_to_wifi, daemon=True).start() def connect_to_wifi(self): ssid = self.selected_network.get() password = self.password.get() if not ssid: self.status_message.set("Please select a Wi-Fi network") return self.status_message.set(f"Connecting to {ssid}...") self.update() try: result = subprocess.run( ["nmcli", "dev", "wifi", "connect", ssid, "password", password], capture_output=True, text=True ) if result.returncode == 0: self.status_message.set(f"Successfully connected to {ssid}") self.update_current_connection() else: error_message = result.stderr.strip() if "802-11-wireless-security.psk: property is invalid" in error_message: self.status_message.set("Incorrect password. Please try again") elif "No network with SSID" in error_message: self.status_message.set("Selected network is unavailable") else: self.status_message.set("Connection failed") self.reset_password() self.password_entry.focus() except Exception as e: self.status_message.set(f"Error: {e}") def update_current_connection(self): try: ssid_result = subprocess.run( ["nmcli",
Editor is loading...
Leave a Comment