Измените локаль, создав объекты wxLocale в wxpython 3.0.2.0 - PullRequest
0 голосов
/ 14 января 2019

Я поддерживаю устаревшее приложение Python 2 и пытаюсь перейти с wxpython 2.8.12.1 на 3.0.2 - получаю следующее сообщение об ошибке:

 Traceback (most recent call last):
      File "Wrye Bash Launcher.pyw", line 88, in <module>
        bash.main()
      File "bash\bash.py", line 428, in main
        frame = app.Init() # Link.Frame is set here !
      File "bash\basher\__init__.py", line 4316, in Init
        size=settings['bash.frameSize'])
      File "bash\basher\__init__.py", line 3906, in __init__
        self.SetStatusBar(BashStatusBar(self))
      File "bash\basher\__init__.py", line 3669, in __init__
        self.UpdateIconSizes()
      File "bash\basher\__init__.py", line 3707, in UpdateIconSizes
        self._addButton(link)
      File "bash\basher\__init__.py", line 3681, in _addButton
        gButton = link.GetBitmapButton(self,style=wx.NO_BORDER)
      File "bash\basher\app_buttons.py", line 657, in GetBitmapButton
        image=staticBitmap(window, special='undo', size=(size,size)))
      File "bash\balt.py", line 509, in staticBitmap
        return bmp(wx.ART_UNDO,wx.ART_TOOLBAR,size)
      File "C:\_\Python27\lib\site-packages\wx-3.0-msw\wx\_misc.py", line 3013, in ArtProvider_GetBitmap
        return _misc_.ArtProvider_GetBitmap(*args, **kwargs)
    wx._core.PyAssertionError: C++ assertion "strcmp(setlocale(LC_ALL, NULL), "C") == 0" failed at ..\..\src\common\intl.cpp(1449) in wxLocale::GetInfo(): You probably called setlocale() directly instead of using wxLocale and now there is a mismatch between C/C++ and Windows locale.
    Things are going to break, please only change locale by creating wxLocale objects to avoid this!

Там написано:

Вы, вероятно, вызывали setlocale () напрямую вместо использования wxLocale, и теперь существует несоответствие между C / C ++ и языковым стандартом Windows

(что такое Windows и что такое C / C ++?)

Ну, это я сделал так:

#--Do translator test and set
if locale.getlocale() == (None,None):
    locale.setlocale(locale.LC_ALL,u'')
initTranslator(language)

В документах locale.setlocale мы читаем:

Приложения обычно начинаются с вызова

import locale
locale.setlocale(locale.LC_ALL, '')

Это устанавливает языковой стандарт для всех категорий на значение по умолчанию для пользователя

Затем в программе все функции с поддержкой локали определяются по всему , как в :

def formatInteger(value):
    """Convert integer to string formatted to locale."""
    return decode(locale.format('%d', int(value), True),
                  locale.getpreferredencoding())

Пропуск вызова locale.setlocale позволяет запустить программу, но я не верю, что эти функции будут полезны (редактирование: подтверждено).

Есть похожие вопросы, как в wx.Image выбрасывает PyAssertionError , но предложенное решение изменяет локаль wx.App, пока вызов setlocale в моем коде выполняется задолго до того, как wx будет даже импортирован. Люди также используют конструкции как wx.Locale(wx.LANGUAGE_ENGLISH), но это, очевидно, хак, я не хочу принудительно переводить локаль пользователя на английский - для другого хака см. здесь

Приведенный выше метод initTranslator использует стандартный механизм gettext и msgfmt.

ВОПРОС

Мне нужен стандартный не хакерский способ заменить вызов locale.setlocale на аналог wx, не нарушая перевод и части программы, учитывающие языковые стандарты. У меня этот вопрос почти четыре года, и я не нашел никакого канонического ответа.

EDIT : пропуск вызова setlocale не влияет на перевод (уууу!), Но действительно нарушает функции отображения с учетом локали.

EDIT2 : замена вышеуказанного вызова на:

-    # if locale.getlocale() == (None,None):
-    #     locale.setlocale(locale.LC_ALL,u'')
+    if locale.getlocale() == (None,None):
+        # locale.setlocale(locale.LC_ALL,u'')
+        import wx
+        wx.Locale(wx.LANGUAGE_DEFAULT)
     if not lang:

выводит кучу предупреждений:

7:12:22 AM: Debug: ..\..\src\common\stdpbase.cpp(56): assert "traits" failed in wxStandardPathsBase::Get(): create wxApp before calling this
7:12:41 AM: Debug: ..\..\src\common\stdpbase.cpp(56): assert "traits" failed in wxStandardPathsBase::Get(): create wxApp before calling this
7:12:42 AM: Debug: ..\..\src\common\stdpbase.cpp(56): assert "traits" failed in wxStandardPathsBase::Get(): create wxApp before calling this
7:12:42 AM: Debug: ..\..\src\common\platinfo.cpp(171): assert "wxAssertFailure" failed in wxPlatformInfo::InitForCurrentPlatform(): failed to initialize wxPlatformInfo
7:12:52 AM: Debug: ..\..\src\common\platinfo.cpp(109): assert "value" failed in wxGetIndexFromEnumValue(): invalid enum value
7:13:12 AM: Debug: ..\..\src\common\platinfo.cpp(240): assert "idx < (sizeof(wxPortIdNames)/sizeof(wxPortIdNames[0]))" failed in wxPlatformInfo::GetPortIdName(): invalid port id

Итак, мне нужно создать wx.App (я бы очень хотел этого избежать, так как хочу иметь возможность переводить (возможно, фатальные) сообщения об ошибках задолго до создания wx.App)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...