import PySimpleGUI as sg
from psgtray import SystemTray
import pyaudio
import threading
def findAudioDevices():
p = pyaudio.PyAudio()
info = p.get_host_api_info_by_index(0)
numdevices = info.get('deviceCount')
device_info = ""
for i in range(0, numdevices):
if (p.get_device_info_by_host_api_device_index(0, i).get('maxInputChannels')) > 0:
device_info += f"Input Device ID {i} - {p.get_device_info_by_host_api_device_index(0, i).get('name')}\n"
sg.popup('Audio Devices', device_info)
# PySimpleGUI setup
menu_def = ['File', ['Show Audio Devices', 'Open Config', 'Exit']]
tooltip = 'Tooltip'
# Initialize the tray
tray = SystemTray(menu=menu_def, single_click_events=False, tooltip=tooltip, icon=r'Icon.png')
tray.show_message('Sound Switch', 'Sound Switchs Started!')
# Event loop
while True:
menu_item = tray.key
if menu_item == 'Exit':
break
elif menu_item == 'Show Audio Devices':
findAudioDevices() # This function should probably be modified to display a popup instead of printing to console
elif menu_item == 'Open Config':
os.system(f"notepad {config_path}")
tray.close()
leads to this error
An error occurred when calling message handler
Traceback (most recent call last):
File "C:\Users\willwade\.pyenv\pyenv-win\versions\3.11.4\Lib\site-packages\pystray\_win32.py", line 398, in _dispatcher
return int(icon._message_handlers.get(
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\willwade\.pyenv\pyenv-win\versions\3.11.4\Lib\site-packages\pystray\_win32.py", line 210, in _on_notify
descriptors[index - 1](self)
File "C:\Users\willwade\.pyenv\pyenv-win\versions\3.11.4\Lib\site-packages\pystray\_base.py", line 308, in inner
callback(self)
File "C:\Users\willwade\.pyenv\pyenv-win\versions\3.11.4\Lib\site-packages\pystray\_base.py", line 434, in __call__
return self._action(icon, self)
^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\willwade\.pyenv\pyenv-win\versions\3.11.4\Lib\site-packages\psgtray\psgtray.py", line 138, in _on_clicked
self.window.write_event_value(self.key, item.text)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'write_event_value'
So it looks like its ignoring sg and using psgtray - but I dont get it. I have a feeling its something to do with the window thread but I have no idea how to fix this?
It looks like you removed the code for the hidden window, also no value for option window
when initiate the SystemTray
.
The PySimpleGUI architecture implemented the tray icon using the psgtray package combined with the overall window event loop, a Window object is still required.
Revised code to
import os
import PySimpleGUI as sg
from psgtray import SystemTray
import pyaudio
import threading
def findAudioDevices():
p = pyaudio.PyAudio()
info = p.get_host_api_info_by_index(0)
numdevices = info.get('deviceCount')
device_info = ""
for i in range(0, numdevices):
if (p.get_device_info_by_host_api_device_index(0, i).get('maxInputChannels')) > 0:
device_info += f"Input Device ID {i} - {p.get_device_info_by_host_api_device_index(0, i).get('name')}\n"
sg.popup('Audio Devices', device_info)
# PySimpleGUI setup
menu_def = ['File', ['Show Audio Devices', 'Open Config', 'Exit']]
tooltip = 'Tooltip'
layout = [[sg.T('Empty Window', key='-T-')]]
window = sg.Window('Window Title', layout, finalize=True, enable_close_attempted_event=True, alpha_channel=0)
window.hide()
# Initialize the tray
tray = SystemTray(menu=menu_def, single_click_events=False, tooltip=tooltip, window=window)
tray.show_message('Sound Switch', 'Sound Switchs Started!')
# Event loop
while True:
event, values = window.read()
menu_item = values[event]
if menu_item == 'Exit':
break
elif menu_item == 'Show Audio Devices':
findAudioDevices() # This function should probably be modified to display a popup instead of printing to console
elif menu_item == 'Open Config':
sg.popup(menu_item)
# os.system(f"notepad {config_path}")
tray.close()
window.close()