복붙노트

[PYTHON] GTK3에서 gettext에 대한 텍스트 폴더를 로컬 폴더에 바인딩하는 방법

PYTHON

GTK3에서 gettext에 대한 텍스트 폴더를 로컬 폴더에 바인딩하는 방법

gettext를 사용하면 기본 시스템 범위의 로켈 디렉토리를 사용하거나 bindtextdomain을 사용하여 직접 지정할 수도 있습니다. 컴파일 된 .mo 변환 파일을 시스템의 기본 위치에서 사용할 수없는 경우 소스에서 직접 프로그램을 실행할 때 유용합니다.

파이썬에서는 이렇게 할 것입니다 :

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

여기서 / path / to / mo / 폴더에는 익숙한 fr / LC_MESSAGES / nautilus-image-manipulator.mo 구조가 포함되어 있습니다. 다음과 같이 호출합니다.

print _("Delete this profile")

제대로 번역 된 문자열을 로컬 .mo 파일에서 반환하십시오. 정말 고마워요.

GTK + 2 / pygtk에는 gtk.glade.bindtextdomain이 있지만 GTK + 3 / PyGObject에 해당하는 것이 있는지 궁금합니다.

특정 예제를 제공하기 위해 Nautilus Image Manipulator UI가 Glade 파일에서 생성되는 방법입니다.

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

Glade 파일 (코드에서 설정)에서 빌드되지 않은 UI 부분은 올바르게 번역되어 표시되지만 Glade 파일의 문자열은 여전히 ​​영어로 표시됩니다.

builder.set_translation_domain을 호출하기 전에 어떤 종류의 builder.bind_text_domain ( 'nautilus-image-manipulator', '/ path / to / mo / folder') 호출을 놓친 것 같습니다. 이것을 수행하는 방법?

해결법

  1. ==============================

    1.PyGtk에서는 Gtk.Builder도 사용할 수 있습니다. PyGtk Gtk.Builder 문서에 따라 :

    PyGtk에서는 Gtk.Builder도 사용할 수 있습니다. PyGtk Gtk.Builder 문서에 따라 :

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

    즉, Gtk.Builder는 "C 라이브러리"의 dgettext ()를 사용합니다. 문제는 Python의 gettext 모듈 인 bindtextdomain () 함수가 "C 라이브러리"를 설정하지 않았다는 것입니다. 옵션은 해당 인터페이스를 노출하는 로케일 모듈을 사용하는 것입니다. 파이썬 로켈 모듈 문서에서 :

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

    현재 상황입니다. 무슨 해킹인가 : S

    이렇게하면된다. 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()
    

    My 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>
    

    다음과 같이 추출한 .po를 기반으로 mo / LANG / LC_MESSAGES / myapp.mo에 mo를 작성하십시오.

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

    모양은 다음과 같습니다.

    종류는 안부

  2. ==============================

    2.Windows에서 Gtk / python의 gettext 번역을 활성화하는 솔루션은 elib_intl.py입니다. Google로 파일을 쉽게 찾을 수 있습니다. 이렇게하면 글 레이드 UI의 코드와 텍스트에서 텍스트를 번역 할 수 있습니다.

    Windows에서 Gtk / python의 gettext 번역을 활성화하는 솔루션은 elib_intl.py입니다. Google로 파일을 쉽게 찾을 수 있습니다. 이렇게하면 글 레이드 UI의 코드와 텍스트에서 텍스트를 번역 할 수 있습니다.

    다음은 다음 환경에서 사용되는 코드입니다.

    윈도우 7 파이썬 2.7 Gtk 3+로드 중 : pygi-aio-3.10.2-win32_rev18-setup.exe

    모든 창과 Python 3에서 작동해야합니다. elib_intl.py는 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")
    

    Gtk 3을 사용하고 있다면, 아마도 오류 메시지를 보게 될 것입니다. 라인 447 :

    libintl = cdll.intl
    

    이 오류는 다음을 나타냅니다. 모듈을 찾을 수 없습니다. 그 이유는 Gtk3에서 dll의 이름이 변경 되었기 때문입니다. 더 이상 intl.dll이 아닙니다. 설명 된 Pygi 설치에서 이름은 libintl-8입니다. 다음과 같이 오류를 증명하는 행을 대체해야합니다.

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

    전체 예제는 pdfBooklet 2.4.0에서 찾을 수 있습니다. (경고 : 쓸 때 아직 줄을 서지 않음)

    elib_intl을 작성한 Dieter Verfaillie에게 감사드립니다.

  3. ==============================

    3.현상금이 Mac OS X 대답을 끌어들이는 데 너무 비참하게 실패한 후에도, 나는 내 자신의 연구를해야했다. 다음은 내가 사용하는 스 니펫입니다.

    현상금이 Mac OS X 대답을 끌어들이는 데 너무 비참하게 실패한 후에도, 나는 내 자신의 연구를해야했다. 다음은 내가 사용하는 스 니펫입니다.

    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('')
    

    나중에 Gtk.Builder를 사용할 때 도메인을 설정하십시오.

    builder.set_translation_domain('domain')
    

    gettext의 라이브러리 libintl이 라이브러리 경로에있는 경우에만 작동하며, 그렇지 않으면 정상적으로 실패합니다. transalion이 작동하려면 gettext를 의존성으로 설치해야합니다.

  4. from https://stackoverflow.com/questions/10094335/how-to-bind-a-text-domain-to-a-local-folder-for-gettext-under-gtk3 by cc-by-sa and MIT license