11import tkinter as tk
2+ from tkinter import ttk
23import subprocess
4+ import json
5+ import threading
6+ import pystray
7+ import sys
8+ import os
9+ from pystray import MenuItem as item
10+ from PIL import Image
11+
12+
13+ def resource_path (relative_path ):
14+ """ Get absolute path to resource, works for dev & PyInstaller """
15+ try :
16+ base_path = sys ._MEIPASS
17+ except AttributeError :
18+ base_path = os .path .abspath ("." )
19+
20+ return os .path .join (base_path , relative_path )
21+
322
423def run_powershell (command ):
524 result = subprocess .run (
@@ -9,95 +28,152 @@ def run_powershell(command):
928 return result
1029
1130def get_display_adapters ():
12- """Fetch all GPUs with their name and instance ID"""
1331 command = """
14- Get-PnpDevice -Class Display |
32+ Get-PnpDevice -Class Display |
1533 Where-Object { $_.InstanceId -ne $null } |
1634 Select-Object -Property FriendlyName, InstanceId |
1735 ConvertTo-Json
1836 """
1937 result = run_powershell (command )
2038 try :
21- import json
2239 parsed = json .loads (result .stdout )
2340 return parsed if isinstance (parsed , list ) else [parsed ]
24- except Exception as e :
41+ except :
2542 return []
2643
2744def get_gpu_status (instance_id ):
2845 try :
2946 result = run_powershell (f"(Get-PnpDevice -InstanceId '{ instance_id } ').Status" )
3047 code = result .stdout .strip ()
31- return "ENABLED ✅ " if code == "OK" else "DISABLED ❌ "
32- except Exception as e :
33- return f"ERROR: { e } "
48+ return "ENABLED" if code == "OK" else "DISABLED"
49+ except :
50+ return "UNKNOWN "
3451
3552def refresh_status ():
3653 selected = selected_gpu .get ()
3754 instance_id = gpu_map .get (selected )
3855 if not instance_id :
39- status_var .set ("No GPU Selected ❌" )
56+ status_var .set ("NO GPU ❌" )
4057 return
41- status_var .set (get_gpu_status (instance_id ))
42- if "ENABLED" in status_var .get ():
43- toggle_var .set ("enable" )
44- elif "DISABLED" in status_var .get ():
45- toggle_var .set ("disable" )
58+ status = get_gpu_status (instance_id )
59+ status_var .set (f"{ status } ✅" if status == "ENABLED" else f"{ status } ❌" )
60+ toggle_var .set (status .lower ())
4661
4762def toggle_gpu ():
48- selected = selected_gpu .get ()
49- instance_id = gpu_map .get (selected )
50- if not instance_id :
51- output_text .set ("No GPU selected." )
52- return
53- choice = toggle_var .get ()
54- if choice == "enable" :
55- result = run_powershell (f'Enable-PnpDevice -InstanceId "{ instance_id } " -Confirm:$false' )
56- output_text .set ("✅ GPU Enabled!\n \n " + result .stdout + result .stderr )
57- elif choice == "disable" :
58- result = run_powershell (f'Disable-PnpDevice -InstanceId "{ instance_id } " -Confirm:$false' )
59- output_text .set ("❌ GPU Disabled!\n \n " + result .stdout + result .stderr )
60- refresh_status ()
63+ def toggle ():
64+ selected = selected_gpu .get ()
65+ instance_id = gpu_map .get (selected )
66+ if not instance_id :
67+ output_text .set ("❌ No GPU selected." )
68+ return
69+ loading_var .set (True )
70+ root .update ()
71+
72+ choice = toggle_var .get ()
73+ if choice == "enabled" :
74+ result = run_powershell (f'Enable-PnpDevice -InstanceId "{ instance_id } " -Confirm:$false' )
75+ elif choice == "disabled" :
76+ result = run_powershell (f'Disable-PnpDevice -InstanceId "{ instance_id } " -Confirm:$false' )
77+
78+ output_text .set (f"✅ GPU { choice .upper ()} !\n \n " + result .stdout + result .stderr )
79+ refresh_status ()
80+ loading_var .set (False )
81+
82+ threading .Thread (target = toggle ).start ()
83+
84+ def update_loading_indicator ():
85+ def loop ():
86+ if loading_var .get ():
87+ current = loading_label .cget ("text" )
88+ next_text = {
89+ "" : "LOADING." ,
90+ "LOADING." : "LOADING.." ,
91+ "LOADING.." : "LOADING..." ,
92+ "LOADING..." : "LOADING."
93+ }.get (current , "LOADING." )
94+ loading_label .config (text = next_text )
95+ else :
96+ loading_label .config (text = "" )
97+ root .after (300 , loop )
98+ loop ()
99+
100+ def create_tray_icon ():
101+ def on_exit ():
102+ icon .stop ()
103+ root .quit ()
104+
105+ def show_window ():
106+ root .deiconify ()
107+ root .lift ()
108+ icon_path = resource_path ("gamer.ico" )
109+ icon_img = Image .open (icon_path )
110+ menu = (item ('Show' , show_window ), item ('Exit' , on_exit ))
111+ icon = pystray .Icon ("GPU_Toggler" , icon_img , "GPU Toggler" , menu )
112+ threading .Thread (target = icon .run , daemon = True ).start ()
61113
62- # Init
63114gpus = get_display_adapters ()
64115gpu_map = {gpu ["FriendlyName" ]: gpu ["InstanceId" ] for gpu in gpus }
65116
66- # GUI Setup
67117root = tk .Tk ()
68- root .title ("Dynamic GPU Toggle Switch" )
69- root .geometry ("500x400" )
118+ root .title ("🧠 GPU Toggler: GAMER MODE 🔥" )
119+ root .geometry ("600x500" )
120+ root .configure (bg = "#0F0F0F" )
70121
71122selected_gpu = tk .StringVar ()
72- selected_gpu .set (next (iter (gpu_map ), "No GPU Found" ))
73-
123+ selected_gpu .set (next (iter (gpu_map ), "NO GPU FOUND" ))
74124toggle_var = tk .StringVar ()
75125status_var = tk .StringVar ()
76126output_text = tk .StringVar ()
127+ loading_var = tk .BooleanVar (value = False )
77128
78129def on_gpu_select (* args ):
79130 refresh_status ()
80-
81131selected_gpu .trace ("w" , on_gpu_select )
82132
83- tk .Label (root , text = "🖥️ Select Your GPU" , font = ("Arial" , 14 )).pack (pady = 10 )
84- tk .OptionMenu (root , selected_gpu , * gpu_map .keys ()).pack (pady = 5 )
85-
86- tk .Label (root , textvariable = status_var , font = ("Arial" , 14 )).pack (pady = 5 )
87-
88- # Radio buttons
89- radio_frame = tk .Frame (root )
133+ style = ttk .Style ()
134+ style .theme_use ('clam' )
135+ style .configure ("TLabel" , background = "#0F0F0F" , foreground = "#08F7FE" , font = ("Consolas" , 12 ))
136+ style .configure ("TButton" , font = ("Consolas" , 12 ), background = "#1A1A1A" , foreground = "#08F7FE" , padding = 6 )
137+ style .configure ("TRadiobutton" , background = "#0F0F0F" , foreground = "#08F7FE" , font = ("Consolas" , 12 ))
138+ style .configure ("TFrame" , background = "#0F0F0F" )
139+
140+ ttk .Label (root , text = "🎮 SELECT GPU TO TOGGLE ⚙️" , font = ("Consolas" , 16 , "bold" ), foreground = "#00FFAA" , background = "#0F0F0F" ).pack (pady = 15 )
141+
142+ option_menu = tk .OptionMenu (root , selected_gpu , * gpu_map .keys ())
143+ option_menu .config (
144+ font = ("Consolas" , 12 ),
145+ bg = "#1A1A1A" ,
146+ fg = "#08F7FE" ,
147+ activebackground = "#222" ,
148+ activeforeground = "#00FFAA" ,
149+ highlightthickness = 2 ,
150+ highlightbackground = "#08F7FE"
151+ )
152+ option_menu .pack (pady = 5 )
153+
154+ status_label = ttk .Label (root , textvariable = status_var , font = ("Consolas" , 14 , "bold" ))
155+ status_label .pack (pady = 10 )
156+
157+ radio_frame = ttk .Frame (root )
90158radio_frame .pack (pady = 10 )
91159
92- tk .Radiobutton (radio_frame , text = "✅ Enable GPU" , variable = toggle_var , value = "enable" ,
93- command = toggle_gpu , bg = "green" , fg = "white" , indicatoron = 0 , width = 30 ).pack (pady = 5 )
160+ ttk .Radiobutton (radio_frame , text = "🟢 ENABLE GPU" , variable = toggle_var , value = "enabled" , command = toggle_gpu ).pack (pady = 5 )
161+ ttk .Radiobutton (radio_frame , text = "🔴 DISABLE GPU" , variable = toggle_var , value = "disabled" , command = toggle_gpu ).pack (pady = 5 )
162+
163+ loading_label = ttk .Label (root , text = "" , font = ("Consolas" , 12 ), foreground = "#08F7FE" , background = "#0F0F0F" )
164+ loading_label .pack (pady = 5 )
94165
95- tk .Radiobutton (radio_frame , text = "❌ Disable GPU" , variable = toggle_var , value = "disable" ,
96- command = toggle_gpu , bg = "red" , fg = "white" , indicatoron = 0 , width = 30 ).pack (pady = 5 )
166+ ttk .Button (root , text = "🔄 REFRESH STATUS" , command = refresh_status ).pack (pady = 15 )
97167
98- tk .Button (root , text = "🔄 Refresh Status" , command = refresh_status , bg = "gray" , fg = "white" , width = 30 ).pack (pady = 10 )
99- tk .Label (root , textvariable = output_text , wraplength = 450 , justify = "left" , font = ("Courier" , 10 )).pack (pady = 10 )
168+ output_label = ttk .Label (
169+ root , textvariable = output_text ,
170+ wraplength = 550 , justify = "left" ,
171+ font = ("Consolas" , 10 ), background = "#0F0F0F" , foreground = "#DDDDDD"
172+ )
173+ output_label .pack (pady = 10 )
100174
175+ update_loading_indicator ()
176+ create_tray_icon ()
101177refresh_status ()
102178
103179root .mainloop ()
0 commit comments