Я поддерживаю устаревшее приложение 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)