Расширяет tk.OptionMenu
для возврата выбранного аудиоустройства.
return self._devices.get(self.selected.get(), None)
Core Point :
Вместо сохранения индекса устройства, которое не синхронизировано c с get_device_count()
, сохраните все устройство в dict
с key == device['name']
.
device = p.get_device_info_by_index(i)
devices[device.get("name")] = device
Импорт, имитация PyAudio :
import tkinter as tk
# Simulating PyAudio
class PyAudio:
def __init__(self):
self._devices = [{'name': 'Device 1', 'maxInputChannels': 0},
{'name': 'Device 2', 'maxInputChannels': 1},
{'name': 'Device 3', 'maxInputChannels': 0},
{'name': 'Device 4', 'maxInputChannels': 2},
{'name': 'Device 5', 'maxInputChannels': 3},
]
def get_device_count(self):
return len(self._devices)
def get_device_info_by_index(self, i):
return self._devices[i]
Расширяет tk.OptionMenu
:
class Microphones(tk.OptionMenu):
def __init__(self, parent, **kwargs):
self.selected = tk.StringVar()
self._devices = kwargs.pop('devices', ())
options = tuple(self._devices.keys())
super().__init__(parent, self.selected, *options, **kwargs)
self.selected.set(options[0])
@property
def device(self):
return self._devices.get(self.selected.get(), None)
Использование :
class App(tk.Tk):
def __init__(self):
super().__init__()
self.micDropDown = Microphones(self, devices=self.getMicrophones(), command=self.on_selected)
self.micDropDown.pack()
def on_selected(self, event):
print(f'on_selected({self.micDropDown.selected.get()}, '
f'device={self.micDropDown.device})')
def getMicrophones(self):
"""
import pyaudio
p = pyaudio.PyAudio()
"""
p = PyAudio()
devices = {}
for i in range(p.get_device_count()):
# if maxInputChannels > 0, then device is a microphone
if p.get_device_info_by_index(i).get("maxInputChannels") > 0:
device = p.get_device_info_by_index(i)
devices[device.get("name")] = device
return devices
if __name__ == '__main__':
App().mainloop()