Skip to Content

Виджет раскладки клавиатуры в QTile

Posted on 3 mins read

В Qtile мне очень не хватало аплета отображающего текущую раскладку клавиатуры и поэтому я решил озадачиться этим вопросам. В прошлой статье я описал как получить текущую раскладку клавиатуры в Python, теперь осталось прикрутить это к qtile. Что оказалось совсем не сложно сделать. За основу я взял виджет часов, который является TextBox’ом. Весь Qtile у меня находить в директории

/usr/local/lib/python2.7/dist-packages/libqtile/

виджеты во вложеной директории widget
Класс виджета часов выглядит следующим образом:

import datetime
from .. import hook, bar, manager
import base

class Clock(base._TextBox):
    """
        A simple but flexible text-based clock.
    """
    defaults = manager.Defaults(
        ("font", "Arial", "Clock font"),
        ("fontsize", None, "Clock pixel size. Calculated if None."),
        ("padding", None, "Clock padding. Calculated if None."),
        ("background", "000000", "Background colour"),
        ("foreground", "ffffff", "Foreground colour")
    )
    def __init__(self, fmt="%H:%M", width=bar.CALCULATED, **config):
        """
            - fmt: A Python datetime format string.

            - width: A fixed width, or bar.CALCULATED to calculate the width
            automatically (which is recommended).
        """
        self.fmt = fmt
        base._TextBox.__init__(self, " ", width, **config)

    def _configure(self, qtile, bar):
        base._TextBox._configure(self, qtile, bar)
        self.timeout_add(1, self.update)

    def update(self):
        now = datetime.datetime.now().strftime(self.fmt)
        if self.text != now:
            self.text = now
            self.bar.draw()
        return True
Как видно в методе update производиться присвоение значения текстового поля, в _configure прописывается обновлять виджет каждую секунду, что для нас является очень полезным. Скопируем данный класс под именем kblayout.py. Это и будет наш новый виджет. Так же в директорию с виджетами необходимо скопировать класс который занимется получением текущей раскладки клавиатуры из прошлой статьи под именем kb.py.
После изменения kblayout.py получаем:
from .. import hook, bar, manager
import base
import subprocess
from kb import kb


class kblayout(base._TextBox):
    """
        A simple but flexible text-based kblayout.
    """
    defaults = manager.Defaults(
        ("font", "Arial", "kblayout font"),
        ("fontsize", None, "kblayout pixel size. Calculated if None."),
        ("padding", None, "kblayout padding. Calculated if None."),
        ("background", "000000", "Background colour"),
        ("foreground", "ffffff", "Foreground colour")
    )

    def __init__(self, width=bar.CALCULATED, **config):
        base._TextBox.__init__(self, "ru", width, **config)

    def _configure(self, qtile, bar):
        base._TextBox._configure(self, qtile, bar)
        self.timeout_add(1, self.update)

    def update(self):
        k = kb()
        l = k.curkb()
        if self.text != l:
            self.text = l
            self.bar.draw()
        return True
Тут у меня вылезлал какая то проблема с gobject, который используется в qtile, которую я так и не смог решить, но смог ее обойти. Для этого в kb.py добавляем строку

del sys.modules['gobject']

получается

import sys
import os
import subprocess
os.environ['GI_TYPELIB_PATH'] =\
    'libxklavier:' + os.environ.get('GI_TYPELIB_PATH', '')

del sys.modules['gobject']
from gi.repository import Xkl, Gdk, GdkX11


class kb():

    def __init__(self):
        display = GdkX11.x11_get_default_xdisplay()
        self.engine = Xkl.Engine.get_instance(display)

    def curkb(self):
        t = subprocess.check_output(["xset", "-q"])
        num = int(t.splitlines()[1].split()[9][4])
        groups = self.engine.get_groups_names()
        if (len(groups) > num):
            return str(groups[int(num)])[:2]
        else:
            return "Err"

k = kb()
print k.curkb()
И в классе виджета mpriswidget.py за меняем строку
import gobject
на
from gi.repository import Xkl, Gdk, GdkX11
Теперь проблем не должно возникнуть. Осталось прописать наш виджет в файл __init__.py директории widget
from kblayout import kblayout
и прописать наш виджет в своем конфиге qtile - ~/.config/qtile/config.py
У меня это выглядит вот так:
screens = [
    Screen(
        top=bar.Bar([widget.GroupBox(
            borderwidth=2, font='Consolas', fontsize=13,
            padding=1, margin_x=1, margin_y=1),
            widget.Sep(),
            widget.WindowName(
                font='Consolas', fontsize=13, margin_x=6),
            widget.Sep(),
            widget.Battery(
                font='Consolas', fontsize=13, margin_x=6,
                energy_now_file="charge_now",
                energy_full_file="charge_full",
                power_now_file="current_now"),
            widget.Sep(),
            widget.Systray(),
            widget.kblayout(font='Consolas', fontsize=13, padding=6),
            widget.Sep(),
            widget.Clock(
                '%H:%M:%S %d.%m.%Y',
                font='Consolas', fontsize=13, padding=6), ], 24,),
    ),
]

comments powered by Disqus