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