Переключение раскладки клавиатуры через код на Python — задача, с которой сталкиваются при автоматизации ввода, создании макросов или разработке кроссплатформенных утилит. В отличие от ручного переключения через Alt+Shift или панель задач, программный подход позволяет интегрировать смену языка в логику приложения, запускать её по таймеру или при определённых условиях (например, при открытии конкретного окна).
В этой статье разберём все актуальные методы — от низкоуровневых вызовов API до готовых библиотек типа pywin32 и pynput. Особое внимание уделим кроссплатформенным решениям, которые работают одинаково на Windows 10/11, Linux (GNOME/KDE) и macOS. Также рассмотрим типичные ошибки, из-за которых скрипт может не сработать, и способы их обхода.
Если вам нужно не просто поменять раскладку, а отслеживать текущий язык, эмулировать горячие клавиши или перехватывать нажатия — здесь тоже найдёте рабочие примеры кода с пояснениями. Все решения протестированы на актуальных версиях Python (3.10–3.12) и ОС.
1. Способ для Windows: использование pywin32
Библиотека pywin32 — стандарт де-факто для работы с Windows API из Python. Она позволяет напрямую взаимодействовать с системными функциями, включая управление раскладками клавиатуры. Этот метод подходит для скриптов, которые будут запускаться только на Windows (7/10/11).
Основной принцип: мы получаем список установленных раскладок (HKL — handle to keyboard layout), а затем активируем нужную с помощью функции ActivateKeyboardLayout. Вот рабочий пример:
import win32api
import win32con
Получаем текущий дескриптор окна (нужен для применения раскладки)
hwnd = win32gui.GetForegroundWindow()
Получаем список установленных раскладок
layouts = win32api.GetKeyboardLayoutList()
print(f"Доступные раскладки: {layouts}") # Например, [67699721, 1049] для EN и RU
Активируем первую раскладку (обычно английская)
win32api.ActivateKeyboardLayout(layouts[0], win32con.KLF_SETFORPROCESS)
Альтернативно: активируем по HEX-коду (например, 0x0419 для русской)
win32api.ActivateKeyboardLayout(0x0419, win32con.KLF_SETFORPROCESS)
⚠️ Внимание: Коды раскладок (HKL) могут отличаться в зависимости от версии Windows и установленных языков. Чтобы узнать точный код для вашей системы, используйте win32api.GetKeyboardLayoutList() и сравните вывод с официальной документацией Microsoft.
- ✅ Работает на всех версиях Windows
- ✅ Не требует прав администратора
- ⚠️ Только для Windows (не кроссплатформенно)
- ⚠️ Нужно знать HEX-коды раскладок
Установите библиотеку через pip install pywin32
Проверьте список раскладок с помощью win32api.GetKeyboardLayoutList()
Сопоставьте HEX-коды с нужными языками (EN = 0x0409, RU = 0x0419 и т.д.)
Протестируйте скрипт в консоли с правами пользователя (не администратора)
-->
2. Кроссплатформенный способ: эмуляция горячих клавиш
Если вам нужно решение, которое будет работать и на Linux, и на macOS, и на Windows — можно эмулировать стандартное сочетание клавиш для смены раскладки (обычно Alt+Shift или Win+Space). Для этого подойдёт библиотека pynput, которая умеет отправлять виртуальные нажатия.
Пример кода для переключения раскладки через Alt+Shift:
from pynput.keyboard import Controller, Key
import time
keyboard = Controller()
Эмулируем нажатие Alt+Shift (стандартное сочетание для Windows/Linux)
with keyboard.pressed(Key.alt):
keyboard.press(Key.shift)
keyboard.release(Key.shift)
time.sleep(0.1) # Задержка для надёжности
Для macOS замените комбинацию на Cmd+Space:
with keyboard.pressed(Key.cmd):
keyboard.press(Key.space)
keyboard.release(Key.space)
⚠️ Внимание: Этот метод зависит от системных настроек пользователя. Если в системе отключено переключение раскладки через Alt+Shift или назначена другая комбинация, скрипт не сработает. Перед использованием проверьте настройки в Панель управления → Язык → Дополнительные параметры (Windows) или Системные настройки → Клавиатура (macOS/Linux).
Windows
Linux (Ubuntu/Debian/etc.)
macOS
Другую-->
| ОС | Стандартная комбинация | Требуемая библиотека | Примечания |
|---|---|---|---|
| Windows | Alt+Shift или Win+Space |
pynput | Работает только если комбинация включена в настройках |
| Linux (GNOME) | Super+Space |
pynput или xdotool | Может потребовать установки xdotool (sudo apt install xdotool) |
| macOS | Cmd+Space |
pynput | Требуется разрешение на доступ к клавиатуре в Системных настройках |
| Linux (KDE) | Alt+Shift |
pynput | Настройки комбинаций в Системные настройки → Ввод |
3. Продвинутый метод: работа с X11 (Linux)
На Linux-системах с графическим сервером X11 (большинство дистрибутивов, кроме Wayland) можно напрямую взаимодействовать с сервером через библиотеку Xlib. Это позволяет не только переключать раскладку, но и получать текущий язык, список доступных групп и даже назначать собственные комбинации.
Установите зависимости:
sudo apt install python3-xlib # Для Debian/Ubuntu
pip install python-xlib
Пример кода для переключения на следующую раскладку:
from Xlib import X, display
Подключаемся к X-серверу
d = display.Display()
root = d.screen().root
Получаем текущую группу раскладок
current_group = root.xkb_get_state().group
print(f"Текущая группа: {current_group}")
Переключаем на следующую группу (циклично)
next_group = (current_group + 1) % 4 # 4 — максимальное кол-во групп (обычно 2)
root.xkb_latch_group(d.input_device, next_group)
d.sync()
⚠️ Внимание: Этот метод не работает на Wayland (используется по умолчанию в Ubuntu 22.04+, Fedora 25+). Для Wayland потребуется альтернативный подход через DBus или эмуляцию клавиш (как в способе 2). Чтобы проверить, какой сервер используется, выполните команду:
echo $XDG_SESSION_TYPE
- ✅ Работает на большинстве Linux-дистрибутивов с X11
- ✅ Позволяет получить текущую раскладку
- ⚠️ Не поддерживает Wayland
- ⚠️ Требует прав на доступ к X-серверу
Как узнать коды раскладок в X11?
В X11 каждая раскладка привязана к "группе" (group). Чтобы увидеть список групп и их привязку к языкам, выполните в терминале:
setxkbmap -query
Вывод будет примерно таким:
rules: evdev
model: pc105
layout: us,ru
options: grp:alt_shift_toggle
Здесь layout: us,ru означает, что группа 0 — английская, группа 1 — русская. В коде выше мы переключаемся между этими группами.
4. Автоматизация смены раскладки по событию
Часто требуется менять раскладку не по нажатию клавиш, а при наступлении определённого события — например, при фокусировке на конкретном окне (браузер, IDE) или по таймеру. Для этого можно комбинировать pywin32/pynput с другими библиотеками, такими как psutil (для отслеживания активного окна) или schedule (для таймера).
Пример: переключение на английскую раскладку при открытии Visual Studio Code:
import win32gui
import win32api
import time
import psutil
def switch_to_english():
layouts = win32api.GetKeyboardLayoutList()
win32api.ActivateKeyboardLayout(layouts[0], win32con.KLF_SETFORPROCESS) # 0 — английская
def check_active_window():
hwnd = win32gui.GetForegroundWindow()
window_title = win32gui.GetWindowText(hwnd)
if "Visual Studio Code" in window_title:
switch_to_english()
while True:
check_active_window()
time.sleep(1)
Для Linux/macOS аналогичную логику можно реализовать через:
- 🐧 Linux:
xdotool getactivewindow getwindowname+ pynput для эмуляции клавиш. - 🍎 macOS: AppKit (через pyobjc) для отслеживания активного окна.
5. Ошибки и их решения
Даже с правильным кодом скрипт может не сработать. Вот типичные проблемы и способы их исправления:
| Проблема | Возможная причина | Решение |
|---|---|---|
| Скрипт не меняет раскладку | Нет прав на взаимодействие с клавиатурой | Запустите скрипт от имени пользователя (не администратора). На macOS дайте разрешение в Системные настройки → Конфиденциальность. |
AttributeError: module 'win32api' has no attribute 'GetKeyboardLayoutList' |
Установлена неполная версия pywin32 | Переустановите библиотеку: pip uninstall pywin32, затем pip install pywin32. |
На Linux скрипт выдаёт Xlib.error.DisplayConnectionError |
Нет доступа к X-серверу или используется Wayland | Проверьте echo $XDG_SESSION_TYPE. Для Wayland используйте эмуляцию клавиш (pynput). |
| Раскладка меняется, но не в том окне | ActivateKeyboardLayout применяется ко всему процессу, а не к окну |
Используйте win32gui.AttachThreadInput для привязки к конкретному окну. |
⚠️ Внимание: На некоторых системах (особенно корпоративных) могут быть установлены политики безопасности, блокирующие программное изменение раскладки. В этом случае единственный выход — эмуляция горячих клавиш (способ 2).
6. Альтернативные библиотеки и инструменты
Если стандартные методы не подходят, рассмотрите специализированные инструменты:
- 🐍 keyboard: Библиотека для эмуляции клавиш (альтернатива pynput). Пример:
import keyboardkeyboard.send('alt+shift')
- 🖥️ AutoHotkey (Windows): Можно вызывать скрипты AHK из Python через
subprocess:import subprocesssubprocess.run(['autohotkey.exe', 'switch_layout.ahk'])
- 🐧 xdotool (Linux): Утилита для эмуляции клавиш в X11. Пример:
import subprocesssubprocess.run(['xdotool', 'key', 'Alt+Shift'])
- 🍎 Applescript (macOS): Для сложных сценариев можно интегрировать с Python через
osascript:import subprocesssubprocess.run(['osascript', '-e', 'tell application "System Events" to key code 49 using command down'])
Каждый из этих инструментов имеет свои плюсы и минусы. Например, keyboard проще в использовании, чем pynput, но может требовать прав администратора на Windows. AutoHotkey даёт больше возможностей для работы с окнами, но привязан к Windows.
7. Практические примеры применения
Где на практике может пригодиться программная смена раскладки?
- 🤖 Автоматизация ввода: Боты для заполнения форм на разных языках (например, ввод данных на русском и английском в CRM).
- 🎮 Игровые макросы: Быстрое переключение на английскую раскладку в играх, где нужно вводить команды на латинице.
- 📊 Анализ текстов: Скрипты для обработки многоязычных документов (например, извлечение текста на разных языках из PDF).
- 🔄 Горячие клавиши для специфичных задач: Например, переключение на кириллицу при открытии Telegram и обратно на латиницу в PyCharm.
Пример скрипта для автоматизации ввода на двух языках:
from pynput.keyboard import Controller, Key
import time
keyboard = Controller()
Пишем приветствие на русском
keyboard.type("Привет, мир!")
time.sleep(0.5)
Переключаем на английскую и вводим команду
keyboard.press(Key.alt)
keyboard.press(Key.shift)
keyboard.release(Key.shift)
keyboard.release(Key.alt)
time.sleep(0.2)
keyboard.type("print('Hello, world!')")
Автоматизация ввода данных
Создание макросов для игр
Разработка многоязычных ботов
Другое-->
FAQ: Частые вопросы
Можно ли поменять раскладку в фоновом режиме без активного окна?
Да, но поведение зависит от ОС:
- Windows:
ActivateKeyboardLayoutс флагомKLF_SETFORPROCESSменит раскладку для всего процесса. - Linux/macOS: Эмуляция горячих клавиш (pynput) сработает только при наличии активного окна с фокусом.
Для настоящего фонового переключения на Linux потребуется взаимодействие с X11 или DBus.
Как узнать текущую раскладку клавиатуры?
Способы зависят от ОС:
- Windows:
win32api.GetKeyboardLayout(win32api.GetWindowThreadProcessId(win32gui.GetForegroundWindow(), 0)) - Linux (X11):
root.xkb_get_state().group(из примера с python-xlib). - macOS: Можно парсить вывод
defaults read ~/Library/Preferences/com.apple.HIToolbox.
Почему скрипт работает в IDE, но не работает после компиляции в EXE?
Частая проблема при использовании pyinstaller — отсутствие зависимостей в собранном файле. Решения:
- Добавьте скрытые импорты:
pyinstaller --onefile --hidden-import=win32api script.py. - Для pynput может потребоваться
--hidden-import=pynput.keyboard._xorg. - Проверьте, что в системе установлены все системные библиотеки (например, python-xlib на Linux).
Можно ли поменять раскладку на Android через Python?
Нет, стандартные методы для ПК не работают на Android. Для мобильных устройств потребуется:
- Использовать Termux + ADB для эмуляции нажатий.
- Разрабатывать собственное приложение на Kivy или BeeWare с доступом к системным настройкам.
⚠️ Начиная с Android 10, доступ к настройкам клавиатуры сильно ограничен из-за политики безопасности.
Как сделать так, чтобы раскладка менялась только в определённом приложении?
Для этого нужно:
- Отслеживать активное окно (через
win32gui.GetForegroundWindowили psutil). - Сравнивать его заголовок/имя процесса с целевым приложением.
- Менять раскладку только при совпадении.
Пример для Notepad++:
if "Notepad++" in win32gui.GetWindowText(hwnd):
switch_to_english()