2017-02-05 3 views
2

Моя клавиатура имеет 2 языка клавиатуры, которые я переключил, греческий и английский. Как я могу получить текущий язык клавиатуры? Есть ли какие-нибудь полезные библиотеки, которые могут сделать трюк для меня? Я использую python 3.5.2, Windows 10Как определить текущий язык клавиатуры в python

+0

это системная информация Windows/Linux/Mac. Он может отключать систему, которую вы используете. – furas

+0

@furas окна! –

+0

Возможно, [ответ] (http://stackoverflow.com/a/3425316/5209610) на другой вопрос SO поможет (проконсультируйтесь с обоими ответами на этот пост). Еще один хороший [ответ] (http://unix.stackexchange.com/a/295271) на этом сайте Unix SE. –

ответ

5

Следующий подход, используя библиотеку 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 Замечаниям я исправленное что.

+0

Переключитесь на использование '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

+0

'use_last_error' добавлен здесь для общности. Он защищает последнее значение ошибки потока, в случае, если он изменяется между вызовом функции и получением ошибки, если она терпит неудачу. Значение ошибки доступно как 'ctypes.get_last_error()', которое более надежно, чем вызов 'GetLastError' напрямую. Основная цель перехода на 'WinDLL' состоит в том, чтобы изолировать ваш модуль от других. 'windll' кэширует библиотеки, которые указывают указатели на кеш, и это приводит к конфликтам, когда хотя бы один модуль определяет прототип функции иначе, чем ожидает другой модуль, т. е.« windll »- плохой дизайн. – eryksun

+0

Ваше объяснение 'klid' просто неверно. 0x4090409 не является 0xAAABBBB, где идентификатор языка - 0xBBBB, а идентификатор субязыка - 0xAAA. Идентификатор языка - это младшее слово (16 бит или 4 шестнадцатеричных разряда), то есть 0xBBBB, для которого идентификатор языка - это 10 младших разрядов этого слова, а идентификатор подъязыка - это высокие 6 бит этого слова. – eryksun