liststore combo python translation gettext gtk3 pygobject

python - combo - Cómo enlazar un dominio de texto a una carpeta local para obtener texto bajo GTK3



python gtk api (3)

Bueno, después de que la recompensa fracasó tan miserablemente para atraer una respuesta mac os x, tuve que hacer mi propia investigación. Aquí está el fragmento que utilizo:

import locale, ctypes, sys, os import gettext # setup textdomain and install _() for strings from python gettext.install(''domain'', ''/path/to/locale/dir'') try: if hasattr(locale, ''bindtextdomain''): libintl = locale elif os.name == ''nt'': libintl = ctypes.cdll.LoadLibrary(''libintl-8.dll'') elif sys.platform == ''darwin'': libintl = ctypes.cdll.LoadLibrary(''libintl.dylib'') # setup the textdomain in gettext so Gtk3 can find it libintl.bindtextdomain(''domain'', ''/path/to/locale/dir'') except (OSError, AttributeError): # disable translations altogether for consistency gettext.install('''')

Más tarde, cuando tengas Gtk.Builder, configura el dominio:

builder.set_translation_domain(''domain'')

Esto solo funcionará si la biblioteca libintl gettext está en la ruta de la biblioteca, de lo contrario fallará con gracia. Para que las transacciones funcionen, deberá instalar gettext como una dependencia.

Con gettext puede usar el directorio de configuración regional de todo el sistema predeterminado, o puede especificar uno por sí mismo usando bindtextdomain . Esto es útil cuando se ejecuta un programa directamente desde la fuente cuando los archivos de traducción .mo compilados no están disponibles en la ubicación predeterminada del sistema.

En Python harías esto:

import gettext from gettext import gettext as _ gettext.bindtextdomain(''nautilus-image-manipulator'', ''/path/to/mo/folder'') gettext.textdomain(''nautilus-image-manipulator'')

donde /path/to/mo/folder contiene la estructura familiar fr/LC_MESSAGES/nautilus-image-manipulator.mo . Llama así:

print _("Delete this profile")

devuelva la cadena traducida correctamente de los archivos .mo locales , muchas gracias.

En GTK + 2 / pygtk, existía gtk.glade.bindtextdomain , pero me pregunto si hay algún equivalente en GTK + 3 / PyGObject.

Para darle un ejemplo específico, así es como se crea la interfaz de usuario de Nautilus Image Manipulator; a partir de su archivo Glade:

from gi.repository import Gtk builder = Gtk.Builder() builder.set_translation_domain(''nautilus-image-manipulator'') builder.add_from_file(ui_filename) return builder

Las partes de la interfaz de usuario que no están compiladas desde el archivo Glade (es decir, configuradas desde el código) se muestran correctamente traducidas, pero las cadenas del archivo Glade todavía aparecen en inglés.

Me parece que me está perdiendo una llamada a algún tipo de builder.bind_text_domain(''nautilus-image-manipulator'', ''/path/to/mo/folder'') antes de la llamada a builder.set_translation_domain ... Cualquier idea ¿Cómo realizar esto?


En PyGtk puedes usar Gtk.Builder también. De acuerdo con la documentación de PyGtk Gtk.Builder:

http://developer.gnome.org/pygtk/stable/class-gtkbuilder.html#properties-gtkbuilder

El dominio de traducción utilizado al traducir valores de propiedades que se han marcado como traducibles en las descripciones de la interfaz. Si el dominio de traducción es Ninguno, GtkBuilder usa gettext (), de lo contrario dgettext (). Valor por defecto: Ninguno

Es decir, Gtk.Builder utiliza dgettext () de "biblioteca C". El problema es que el módulo gettext de Python, función bindtextdomain () , por alguna razón desconocida para mí, no configura la "biblioteca C". La opción es usar el módulo de configuración regional que también expone esa interfaz. Desde la documentación del módulo de configuración regional de Python:

http://docs.python.org/library/locale#access-to-message-catalogs

El módulo de configuración regional expone la interfaz gettext de la biblioteca C en los sistemas que proporcionan esta interfaz. Consiste en las funciones gettext (), dgettext (), dcgettext (), textdomain (), bindtextdomain () y bind_textdomain_codeset (). Estas son similares a las mismas funciones en el módulo gettext, pero utilizan el formato binario de la biblioteca C para los catálogos de mensajes y los algoritmos de búsqueda de la biblioteca C para localizar los catálogos de mensajes.

Las aplicaciones de Python normalmente no encontrarán la necesidad de invocar estas funciones, y deberían usar gettext en su lugar. Una excepción conocida a esta regla son las aplicaciones que enlazan con bibliotecas de C adicionales que invocan internamente gettext () o dcgettext (). Para estas aplicaciones, puede ser necesario enlazar el dominio de texto, de modo que las bibliotecas puedan ubicar correctamente sus catálogos de mensajes.

Cuál es el caso actual. Qué hack: S

Esto lo hará, archivo test.py :

from gi.repository import Gtk from os.path import abspath, dirname, join import gettext import locale APP = ''myapp'' WHERE_AM_I = abspath(dirname(__file__)) LOCALE_DIR = join(WHERE_AM_I, ''mo'') locale.setlocale(locale.LC_ALL, '''') locale.bindtextdomain(APP, LOCALE_DIR) gettext.bindtextdomain(APP, LOCALE_DIR) gettext.textdomain(APP) _ = gettext.gettext print(''Using locale directory: {}''.format(LOCALE_DIR)) class MyApp(object): def __init__(self): # Build GUI self.builder = Gtk.Builder() self.glade_file = join(WHERE_AM_I, ''test.glade'') self.builder.set_translation_domain(APP) self.builder.add_from_file(self.glade_file) print(_(''File'')) print(_(''Edit'')) print(_(''Find'')) print(_(''View'')) print(_(''Document'')) # Get objects go = self.builder.get_object self.window = go(''window'') # Connect signals self.builder.connect_signals(self) # Everything is ready self.window.show() def main_quit(self, widget): Gtk.main_quit() if __name__ == ''__main__'': gui = MyApp() Gtk.main()

Mi archivo Glade test.glade :

<?xml version="1.0" encoding="UTF-8"?> <interface> <!-- interface-requires gtk+ 3.0 --> <object class="GtkWindow" id="window"> <property name="can_focus">False</property> <property name="window_position">center-always</property> <property name="default_width">400</property> <signal name="destroy" handler="main_quit" swapped="no"/> <child> <object class="GtkBox" id="box1"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="orientation">vertical</property> <child> <object class="GtkLabel" id="label1"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="label" translatable="yes">File</property> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> <property name="position">0</property> </packing> </child> <child> <object class="GtkLabel" id="label2"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="label" translatable="yes">Edit</property> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> <property name="position">1</property> </packing> </child> <child> <object class="GtkLabel" id="label3"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="label" translatable="yes">Find</property> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> <property name="position">2</property> </packing> </child> <child> <object class="GtkLabel" id="label4"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="label" translatable="yes">View</property> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> <property name="position">3</property> </packing> </child> <child> <object class="GtkLabel" id="label5"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="label" translatable="yes">Document</property> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> <property name="position">4</property> </packing> </child> </object> </child> </object> </interface>

Recuerde crear el mo in mo / LANG / LC_MESSAGES / myapp.mo basado en .po extraído con:

xgettext --keyword=translatable --sort-output -o en.po test.glade

Lo que parece:

Saludos cordiales


La solución para activar las traducciones de gettext en Gtk / python en Windows es elib_intl.py Es fácil encontrar el archivo con Google. Esto permite la traducción del texto en el código y el texto en una interfaz de usuario clara.

Aquí está el código utilizado para el siguiente entorno:

Windows 7 Python 2.7 Gtk 3+ cargado por: pygi-aio-3.10.2-win32_rev18-setup.exe

Debería funcionar en cualquier ventana y también para Python 3. elib_intl.py se puede usar con pyGtk (Gtk 2).

from gi.repository import Gtk, Gdk import cairo import locale #for multilanguage support import gettext import elib_intl elib_intl.install("pdfbooklet", "share/locale")

Si está utilizando Gtk 3, probablemente recibirá un error: para la línea 447:

libintl = cdll.intl

Este error indica: módulo no encontrado. La razón es que en Gtk3, el nombre de la dll ha sido cambiado. Ya no es intl.dll. En la instalación de Pygi descrita el nombre es: libintl-8. Debe reemplazar la línea que provoca el error por:

libintl = cdll.LoadLibrary("libintl-8.dll")

Puede encontrar un ejemplo de trabajo completo aquí: pdfBooklet 2.4.0 (Advertencia: aún no estoy en línea cuando escribo)

gracias a Dieter Verfaillie que ha escrito elib_intl