Untitled
unknown
plain_text
a year ago
9.1 kB
4
Indexable
import customtkinter as ctk
import subprocess
import threading
from tkinter import StringVar
from CTkPopupKeyboard import PopupKeyboard, PopupNumpad # Use correct imports
class WifiConfiguratorApp(ctk.CTk):
def __init__(self):
super().__init__()
self.title("Wi-Fi Configurator")
self.attributes('-fullscreen', True) # Fullscreen for deployment
self.protocol("WM_DELETE_WINDOW", self.close_app) # Enable closing for prototyping
self.networks = []
self.selected_network = StringVar()
self.password = StringVar()
self.show_password = ctk.BooleanVar(value=False)
self.keyboard_visible = ctk.BooleanVar(value=False)
self.current_connection = {
"SSID": "Not connected",
"Signal Strength": "N/A",
"IP Address": "N/A"
}
self.status_message = StringVar(value="Idle")
# UI Elements
self.create_widgets()
self.scan_wifi_networks()
self.update_current_connection()
def create_widgets(self):
# Title Label
title_label = ctk.CTkLabel(self, text="Wi-Fi Configurator", font=("Arial", 32, "bold"))
title_label.pack(pady=10)
# Status Label
self.status_label = ctk.CTkLabel(self, textvariable=self.status_message, font=("Arial", 14), text_color="green")
self.status_label.pack(pady=5)
# Current Connection Details
self.connection_frame = ctk.CTkFrame(self)
self.connection_frame.pack(pady=5, padx=20, fill="x")
connection_title = ctk.CTkLabel(self.connection_frame, text="Current Connection", font=("Arial", 18, "bold"))
connection_title.grid(row=0, column=0, columnspan=2, pady=5)
self.ssid_label = ctk.CTkLabel(self.connection_frame, text="SSID: Not connected")
self.ssid_label.grid(row=1, column=0, padx=5, sticky="w")
self.signal_label = ctk.CTkLabel(self.connection_frame, text="Signal Strength: N/A")
self.signal_label.grid(row=2, column=0, padx=5, sticky="w")
self.ip_label = ctk.CTkLabel(self.connection_frame, text="IP Address: N/A")
self.ip_label.grid(row=3, column=0, padx=5, sticky="w")
# Network Selection
self.network_dropdown = ctk.CTkOptionMenu(self, variable=self.selected_network, values=self.networks)
self.network_dropdown.pack(pady=5)
# Password Entry and Keyboard
password_frame = ctk.CTkFrame(self)
password_frame.pack(pady=5)
password_label = ctk.CTkLabel(password_frame, text="Enter Wi-Fi Password:")
password_label.grid(row=0, column=0, padx=5, pady=5, sticky="w")
self.password_entry = ctk.CTkEntry(
password_frame, textvariable=self.password, show="*")
self.password_entry.grid(row=1, column=0, padx=5, pady=5)
toggle_password_button = ctk.CTkButton(
password_frame, text="Show", width=60, command=self.toggle_password_visibility)
toggle_password_button.grid(row=1, column=1, padx=5, pady=5)
reset_password_button = ctk.CTkButton(
password_frame, text="Reset", width=60, command=self.reset_password)
reset_password_button.grid(row=1, column=2, padx=5, pady=5)
# On-screen Keyboard Switch
switch = ctk.CTkSwitch(self, text="On-Screen Keyboard", command=self.toggle_keyboard)
switch.pack(pady=10)
switch.toggle()
# On-screen Keyboard
self.keyboard_frame = ctk.CTkFrame(self)
self.keyboard_frame.pack(pady=10)
self.keyboard = PopupKeyboard(self.password_entry) # Attach keyboard to password entry
self.keyboard.pack()
# Buttons
button_frame = ctk.CTkFrame(self)
button_frame.pack(pady=10)
connect_button = ctk.CTkButton(button_frame, text="Connect", command=self.start_connecting_to_wifi)
connect_button.grid(row=0, column=0, padx=10)
refresh_button = ctk.CTkButton(button_frame, text="Refresh", command=self.scan_wifi_networks)
refresh_button.grid(row=0, column=1, padx=10)
exit_button = ctk.CTkButton(button_frame, text="Exit (Prototyping)", command=self.close_app)
exit_button.grid(row=0, column=2, padx=10)
def toggle_keyboard(self):
# Toggle the visibility of the keyboard
if self.keyboard_visible.get():
self.keyboard_frame.pack_forget()
self.keyboard_visible.set(False)
else:
self.keyboard_frame.pack(pady=10)
self.keyboard.pack()
self.keyboard_visible.set(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 start_connecting_to_wifi(self):
threading.Thread(target=self.connect_to_wifi).start()
def connect_to_wifi(self):
ssid = self.selected_network.get()
password = self.password.get()
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.")
else:
self.status_message.set(f"Connection failed: {error_message}")
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", "-t", "-f", "ACTIVE,SSID,SIGNAL", "dev", "wifi"],
capture_output=True, text=True
)
ip_result = subprocess.run(
["hostname", "-I"], capture_output=True, text=True
)
if ssid_result.returncode == 0:
for line in ssid_result.stdout.split("\n"):
if line.startswith("yes"):
_, ssid, signal = line.split(":")
self.current_connection["SSID"] = ssid
self.current_connection["Signal Strength"] = f"{signal}%"
break
else:
self.current_connection["SSID"] = "Not connected"
self.current_connection["Signal Strength"] = "N/A"
if ip_result.returncode == 0:
self.current_connection["IP Address"] = ip_result.stdout.strip()
else:
self.current_connection["IP Address"] = "N/A"
self.ssid_label.configure(text=f"SSID: {self.current_connection['SSID']}")
self.signal_label.configure(text=f"Signal Strength: {self.current_connection['Signal Strength']}")
self.ip_label.configure(text=f"IP Address: {self.current_connection['IP Address']}")
except Exception as e:
self.status_message.set(f"Failed to retrieve connection details: {e}")
def toggle_password_visibility(self):
if self.show_password.get():
self.password_entry.configure(show="*")
self.show_password.set(False)
else:
self.password_entry.configure(show="")
self.show_password.set(True)
def reset_password(self):
self.password.set("")
def close_app(self):
self.destroy()
if __name__ == "__main__":
ctk.set_appearance_mode("System")
ctk.set_default_color_theme("blue")
app = WifiConfiguratorApp()
app.mainloop()
Editor is loading...
Leave a Comment