ebranlard / pyDatView

A crossplatform GUI to plot tabulated data from files (e.g. CSV, Excel, OpenFAST, HAWC2, Flex...), or python pandas dataframes
MIT License
110 stars 43 forks source link

Bug with language settings #128

Closed SimonHH closed 1 year ago

SimonHH commented 2 years ago

Hi,

when the settings for the language and the decimal separator are not matching e.g. when the system language is set to german but the decimal seperator is set to be . then the following error is given on startup.

Changing the decimal seperator back to the default value (for german that is ,) the error is gone.

Can you fix that so we can use the german language settings with a . as decimal seperator?

image

Best regards, Simon

ebranlard commented 2 years ago

Hi @SimonHH Thanks for reporting this, that might be a tough one for me to debug as I cannot reproduce it at the moment. I've had some issues like that in the past (on a different project), while in Denmark.

Can you hack your way into the file GUIToolBox.py listed in the error message, and edit it. For instance setting defaultBitmap = None on line 65. If it's only the toolbox button that cause an issue we can likely find a workaround. If the program complains at many other places, it might be more challenging.

Thanks a lot, Emmanuel

SimonHH commented 2 years ago

Hi @ebranlard, I solved this by changing the reginal formatting language in windows to English (e.g. British English is closest to German date formatting). That is sufficient for us. Thus I won't invest in solving this in the code, as I had also difficulties in reproducing the error on my coding machine.

Best regards, Simon

SimonHH commented 2 years ago

Hi @ebranlard, I finally came around to look at this again as there were problems with some excel macros. Anyway I managed to reproduce the error on a different machine with anaconda and tried your suggestion.

pydatview now starts without error but when loading a file the next associated error pops up:

[...] GUIPlotPanel.py", line 438, in __init__ TBAddCheckTool(self.navTBBottom,'', icons.chart.GetBitmap(), self.onEsthToggle) File "[...]\Python\Python39\site-packages\wx\lib\embeddedimage.py", line 49, in GetBitmap return wx.Bitmap(self.GetImage()) File "[...]\Python\Python39\site-packages\wx\lib\embeddedimage.py", line 64, in GetImage return wx.Image(stream) wx._core.wxAssertionError: C++ assertion "wxString::Format("%.3f", 1.23).find(str) != wxString::npos" failed at ..\..\src\common\intl.cpp(1633) inanonymous-namespace'::GetInfoFromLCID(): Decimal separator mismatch -- did you use setlocale()?If so, use wxLocale to change the locale instead.`

So this seems to be a more general topic. Any ideas?

Best regards, Simon

ebranlard commented 1 year ago

Hi Simon,

Sorry for my delay. This seems to be bit of a nasty bug of wxpython, which I believe has been fixed, but we need to wait for future release.

I've tried to push a small quick fix (importing "locale"). Let me know if that helps. You should see the message "[INFO] Setting locale to C", in the terminal. If that doesn't work, you can try uncommenting line 776 of pydatview/main.py, which does app.SetAssertMode(wx.APP_ASSERT_SUPPRESS) , to avoid those C++ assertions...

Here are some references (if we need to dig deeper):
https://github.com/wxWidgets/Phoenix/issues/769 https://github.com/wxWidgets/Phoenix/issues/1751

I think a minimal example would be as follows:

import wx
import sys
from wx.lib.embeddedimage import PyEmbeddedImage
import locale

chart = PyEmbeddedImage(
    b'iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABHNCSVQICAgIfAhkiAAAAAlw'
    b'SFlzAAADEwAAAxMBPWaDxwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA'
    b'AAEzSURBVDiNrdQ7LwRRFADgb2XjEQ0RGgqFRqVReBYKBYWIqFQSnSglfoXST1BoJKIRj0oi'
    b'oZGIV6HyA8hSCckq5pBrrdfYk0xmzp2bb865d3ILmMCS2sRhEYOBFmoAdhWT5A7bOaG+uKTg'
    b'LeZzgqtvYF1OII0ZLIol+y84hXXUo/xfcBIbgb07ecFxbKIB91FlbnAUW1FZCSO4yQsOYweN'
    b'gQ3hOp3wF3AQu2jCQ+BXlZOqgd1YqBgbwH5gpcgvq321WJH34Agt6MUy+rGXVPapza/Adhyj'
    b'FS+yA6MNs2j2TZtppC13BvaEk3g3F9ijbDcvvsNSsBz3J9nfPyZrsxzYKM5/wlKwENh0QM/x'
    b'vBbY2W8wPq5hKSobS8aeZW3P/eCMVAM7sPLbSr6KIk5lm1CLE/vgFRE4ODkTvkH/AAAAAElF'
    b'TkSuQmCC')

print(f'Python {sys.version} on {sys.platform}')
print(f'wx version {wx.__version__}')

app = wx.App() 

# --- Things to try
# locale.setlocale(locale.LC_ALL,'C') # see bug #128
# app.SetAssertMode(wx.APP_ASSERT_SUPPRESS)

for loc in ('en_GB', 'en_US', 'de_DE',  'pl_PL', 'sv_SE', 'fr_FR'):
    print(f'setting wx locale to {loc}')
    cli_target      = wx.Locale.FindLanguageInfo(loc)
    target_language = cli_target.Language
    target_locale   = wx.Locale(target_language)
    target_name     = target_locale.GetCanonicalName()
    chart.GetBitmap()
SimonHH commented 1 year ago

Hi @ebranlard,

your fix seem to work. At least I was not able to produce the error anymore. Thanks a lot!

In case you want to track this in order to include the official fix from wxpython once it is available you can leave this issue open. Otherwise I am fine with closing it.

ebranlard commented 1 year ago

Great! I'm glad it's working. I'll keep it open for a little bit, but it seems like it's going to take a while before there's a fix on the wxpython side.

For reference the fix consisted of adding the following in the wx.App init:

        if sys.platform.startswith('win') and sys.version_info > (3,8):
            # See Bug #128 - Issue with wxPython 4.1 on Windows
            import locale
            locale.setlocale(locale.LC_ALL, "C")
            print('[INFO] Setting locale to C')
            #self.SetAssertMode(wx.APP_ASSERT_SUPPRESS) # Try this
ebranlard commented 1 year ago

I'm closing this for now, thanks again!