Моя клавиатура имеет 2 языка клавиатуры, которые я переключил, греческий и английский. Как я могу получить текущий язык клавиатуры? Есть ли какие-нибудь полезные библиотеки, которые могут сделать трюк для меня? Я использую python 3.5.2, Windows 10Как определить текущий язык клавиатуры в python
ответ
Следующий подход, используя библиотеку ctypes
, работает для меня.
# My keyboard is set to the English - United States keyboard
>>> import ctypes
# For debugging Windows error codes in the current thread
>>> user32 = ctypes.WinDLL('user32', use_last_error=True)
>>> curr_window = user32.GetForegroundWindow()
>>> thread_id = user32.GetWindowThreadProcessId(curr_window, 0)
# Made up of 0xAAABBBB, AAA = HKL (handle object) & BBBB = language ID
>>> klid = user32.GetKeyboardLayout(thread_id)
67699721
# Language ID -> low 10 bits, Sub-language ID -> high 6 bits
# Extract language ID from KLID
>>> lid = klid & (2**16 - 1)
# Convert language ID from decimal to hexadecimal
>>> lid_hex = hex(lid)
'0x409'
# I switched my keyboard to the Russian keyboard
>>> curr_window = user32.GetForegroundWindow()
>>> thread_id = user32.GetWindowThreadProcessId(curr_window, 0)
>>> klid = user32.GetKeyboardLayout(thread_id)
68748313
# Extract language ID from KLID
>>> lid = klid & (2**16 - 1)
# Convert language ID from decimal to hexadecimal
>>> lid_hex = hex(lid)
'0x419'
Вы можете следовать той же процедуре для греческого (0x408
), или любой другой язык, который вы хотели бы обнаружить. Если вам интересно, here is a plain-text list и here is Microsoft's list всех шестнадцатеричных значений, которые lid_hex
могли бы взять на себя, учитывая язык ввода.
Для справки, LCID хранятся в this format (как я описал в комментариях к моему коду).
Просто убедитесь, что вы звоните GetKeyboardLayout(thread_id)
каждый раз, когда вы переключаете языки на клавиатуре.
EDIT:
Как @furas, упомянутые в комментариях, это зависит от системы. Если вы собираетесь переносить свой код на ОС, отличную от Windows 10 (возможно, даже более ранних версий Windows, если с тех пор изменились идентификаторы LCID), этот подход не будет работать должным образом.
EDIT 2:
Моего первое объяснение klid
не было правильным, но благодаря @ eryksun Замечаниям я исправленное что.
Переключитесь на использование 'user32 = ctypes.WinDLL ('user32', use_last_error = True)'. Кроме того, результат «HKL» в ['GetKeyboardLayout'] (https://msdn.microsoft.com/en-us/library/ms646296) имеет идентификатор языка в младшем слове (16 бит), например. 'klid = hkl & (2 ** 16 - 1)'. Идентификатор языка состоит из идентификатора основного языка в младших 10 битах и идентификатора подъязыка в верхних 6 битах, например. 0x409 имеет идентификатор языка 9 ('LANG_ENGLISH') и идентификатор подязыка 1 (' SUBLANG_ENGLISH_US'). – eryksun
'use_last_error' добавлен здесь для общности. Он защищает последнее значение ошибки потока, в случае, если он изменяется между вызовом функции и получением ошибки, если она терпит неудачу. Значение ошибки доступно как 'ctypes.get_last_error()', которое более надежно, чем вызов 'GetLastError' напрямую. Основная цель перехода на 'WinDLL' состоит в том, чтобы изолировать ваш модуль от других. 'windll' кэширует библиотеки, которые указывают указатели на кеш, и это приводит к конфликтам, когда хотя бы один модуль определяет прототип функции иначе, чем ожидает другой модуль, т. е.« windll »- плохой дизайн. – eryksun
Ваше объяснение 'klid' просто неверно. 0x4090409 не является 0xAAABBBB, где идентификатор языка - 0xBBBB, а идентификатор субязыка - 0xAAA. Идентификатор языка - это младшее слово (16 бит или 4 шестнадцатеричных разряда), то есть 0xBBBB, для которого идентификатор языка - это 10 младших разрядов этого слова, а идентификатор подъязыка - это высокие 6 бит этого слова. – eryksun
это системная информация Windows/Linux/Mac. Он может отключать систему, которую вы используете. – furas
@furas окна! –
Возможно, [ответ] (http://stackoverflow.com/a/3425316/5209610) на другой вопрос SO поможет (проконсультируйтесь с обоими ответами на этот пост). Еще один хороший [ответ] (http://unix.stackexchange.com/a/295271) на этом сайте Unix SE. –