Как программно поменять раскладку клавиатуры в Python: от скрипта до GUI

Переключение раскладки клавиатуры через код на 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 keyboard
    

    keyboard.send('alt+shift')

  • 🖥️ AutoHotkey (Windows): Можно вызывать скрипты AHK из Python через subprocess:
    import subprocess
    

    subprocess.run(['autohotkey.exe', 'switch_layout.ahk'])

  • 🐧 xdotool (Linux): Утилита для эмуляции клавиш в X11. Пример:
    import subprocess
    

    subprocess.run(['xdotool', 'key', 'Alt+Shift'])

  • 🍎 Applescript (macOS): Для сложных сценариев можно интегрировать с Python через osascript:
    import subprocess
    

    subprocess.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, доступ к настройкам клавиатуры сильно ограничен из-за политики безопасности.

Как сделать так, чтобы раскладка менялась только в определённом приложении?

Для этого нужно:

  1. Отслеживать активное окно (через win32gui.GetForegroundWindow или psutil).
  2. Сравнивать его заголовок/имя процесса с целевым приложением.
  3. Менять раскладку только при совпадении.

Пример для Notepad++:

if "Notepad++" in win32gui.GetWindowText(hwnd):

switch_to_english()