Awesome Kivy Revelations

We are using kivy for the GUI of the knit editor. It can be used to create Android, Windows, Linux, Mac and IOS apps. You can divide UI-design and code by using the kv language. In this blog post, I want to share some revelations I had when using kivy. This includes showing you how you can update translations automatically when the configuration changes and subtracting values. This awaits you: Automatic Update of Translated Text in the Kivy UI In projects like Django, there is the "_" function that allows translations of text. The implementation usually look calls a "gettext" function of some sort, which takes a string and returns its translation as a string. What we have in the kniteditor, is an observable translation, with the same interface: def _(string): """Translate a string using the current language. :param str string: the string to translate :return: the translated string :rtype: str """ return _locales.gettext(string) _ = ObservableTranslation(_) The difference is that the observable translation can be used like the "_" function but has additional methods that allow the UI to register and be notified when the language changes. When the language is changed, the global "gettext" is replaced by the "gettext" in the new language and, inthe last line, the observers are notified about the change. def change_language_to(new_language): """Change the language to a language from the translations folder. :param str new_language: the language code of the new language """ global _locales, _current_language _locales = gettext.translation(DOMAIN, _locale_dir, languages=[new_language]) _current_language = new_language _.language_changed() To see what this does, we can look at the whole implementation. I would like to give the whole picture, first, as it clarifies the context and discuss them below. """Observable Translations for kivy that change when the language changes. The functionality of this module is highly inspired by `kivy-gettext-example <https://github.com/tito/kivy-gettext-example>`. """ from kivy.lang import Observable class ObservableTranslation(Observable): """This class allows kivy translations to be updated with the language.""" def __init__(self, translate): """Create a new translation object with a translation function. :param translate: a callable that translates the text. Even when the language is changed, it returns the text for the current language. """ super().__init__() self._translate = translate self._observers = [] def __call__(self, text): """Call this object to translate text. :param str text: the text to translate :return: the text translated to the current language """ return self._translate(text) def fbind(self, name, func, args, **kwargs): """Add an observer. This is used by kivy.""" self._observers.append((name, func, args, kwargs)) def funbind(self, name, func, args, **kwargs): """Remove an observer. This is used by kivy.""" key = (name, func, args, kwargs) if key in self._observers: self._observers.remove(key) def language_changed(self): """Update all the kv rules attached to this text.""" for name, func, args, kwargs in self._observers: func(args, None, None) __all__ = ["ObservableTranslation"] The constructor takes the "_" function. When the object is called like a function, the "__call__" method is invoked, translating like "_". If we only have these two methods, the observable translation works just like the "_" function. "fbind" and "funbind" are the methods…

Continue ReadingAwesome Kivy Revelations