为什么 tkinter X 程序通过 SSH 与 MobaXterm 一起工作,但在通过 Windows 子系统为 Linux 使用 SSH 时出错?

Why does tkinter X program work through SSH with MobaXterm, but give an error when using SSH through Windows Subsystem for Linux?

我在做什么

我正在 Windows 10 工作站的远程 Fedora 服务器上编写 Python 程序(前端:tkinter,后端:Python 3.6)。 MobaXterm 有时会在出现异常后停止显示您键入的内容,因此我决定测试 Windows 子系统以获取 Linux.

问题简要说明

当使用 MobaXterm 执行 GUI 时,它会启动,当从子系统执行时,我收到 "AttributeError: 'NoneType' object has no attribute 'days'" 错误。

系统信息

服务器详情

NAME=Fedora
VERSION="27 (Twenty Seven)"
ID=fedora
VERSION_ID=27
PRETTY_NAME="Fedora 27 (Twenty Seven)"
ANSI_COLOR="0;34"
CPE_NAME="cpe:/o:fedoraproject:fedora:27"
HOME_URL="fedoraproject" !!!Link removed because of SPAM flag!!!
SUPPORT_URL=!!!Link removed because of SPAM flag!!!
BUG_REPORT_URL=!!!Link removed because of SPAM flag!!!
REDHAT_BUGZILLA_PRODUCT="Fedora"
REDHAT_BUGZILLA_PRODUCT_VERSION=27
REDHAT_SUPPORT_PRODUCT="Fedora"
REDHAT_SUPPORT_PRODUCT_VERSION=27
PRIVACY_POLICY_URL= !!!Link removed because of SPAM flag!!!

子系统详细信息

NAME="Ubuntu"
VERSION="18.04.2 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.2 LTS"
VERSION_ID="18.04"
HOME_URL=!!!Link removed because of SPAM flag!!!
SUPPORT_URL=!!!Link removed because of SPAM flag!!!
BUG_REPORT_URL=!!!Link removed because of SPAM flag!!!
PRIVACY_POLICY_URL=!!!Link removed because of SPAM flag!!!
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic

一般信息

MobaXterm

个人版v11.1 Build 3860

X11 从 Fedora 服务器转发到 Ubuntu 子系统

使用 VcXsrv(vvcxsrv-64.1.20.1.4) 完成

Windows10 上的导出已经过测试并适用于其他程序(使用 xeyes、firefox 和 display 测试)

export DISPLAY=localhost:0.0

我已经创建了生成问题的代码的简化版本。如果您将以下代码复制并粘贴到 python 实时终端中,它将执行。

这是一个可以更改的日历,点击日历左侧的日期可以将日期重置为当前日期。它与 MobaXterm 一起使用,并在连接

时出错
ssh -X -l username server.yourdomain.com

为 Linux 使用 Windows 子系统。

from tkinter import *
from tkinter import ttk
from tkinter import messagebox
from tkcalendar import Calendar, DateEntry
from datetime import date

# Update the dates in the date_picker variable as well as the date variable
def update_dates(date_frame_container):

    date_frame_container['date_picker'].set_date(date.today())
    date_frame_container['date'] = date_frame_container['date_picker'].get_date()

 # Create an instance of the datepicker and place it on the tab
def setup_date_picker(date_frame_container):

    calendar_style = ttk.Style(date_frame_container['frame'])
    calendar_style.theme_use('clam')

    date_frame_container['date_label'] = ttk.Label(
            date_frame_container['frame'],
            anchor='w',
            text='Today: %s' % date.today().strftime('%x'))
    date_frame_container['date_label'].pack(side = LEFT, anchor = 'w', fill='x')

    date_frame_container['date_picker'] = DateEntry(date_frame_container['frame'])
    date_frame_container['date_picker'].pack(side = RIGHT, anchor = 'e', padx = 10, pady = 10)

    date_frame_container['date_label'].bind("<Button-1>", lambda e : update_dates(date_frame_container))


input_values = {'batch_file': '',
                'scene_id': '',
                'date_frame_container': {
                      'frame': '',
                      'date_picker': '',
                      'date_label': '',
                      'date': ''},
                'lat': '',
                'lon': '',
                'surface_temp': ''}

master = Tk()
master.geometry('320x200')
master.option_add('*tearOff', False)
input_values['date_frame_container']['frame'] = ttk.Frame(master)
input_values['date_frame_container']['frame'].grid(row = 0, column = 1, padx = 10, pady = 10, sticky = 'e')
setup_date_picker(input_values['date_frame_container'])

错误

当 运行使用 MobaXterm 编写代码时它可以工作。

当 运行使用 ssh 和子系统连接代码时,它不起作用,我收到 AttributeError: 'NoneType' object has no attribute 'days' 错误

完整的Traceback如下

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 10, in setup_date_picker
  File "/usr/local/lib/python3.6/site-packages/tkcalendar/dateentry.py", line 93, in __init__
    self._calendar = Calendar(self._top_cal, **kw)
  File "/usr/local/lib/python3.6/site-packages/tkcalendar/calendar_.py", line 211, in __init__
    self._day_names = get_day_names('abbreviated', locale=locale)
  File "/usr/lib/python3.6/site-packages/babel/dates.py", line 305, in get_day_names
    return Locale.parse(locale).days[context][width]
AttributeError: 'NoneType' object has no attribute 'days'

为什么会发生这种情况,我该如何解决?该程序需要在所有环境中 运行(它适用于大学的研究团队,需要使用您能想到的所有操作系统的学生和科学家使用)

正如 Bryan Oakley 所说,这是区域设置的问题,tkcalendar 尝试确定默认区域设置但未找到任何区域设置,因此区域设置设置为 None。因此,任何日期格式化尝试都会失败。

我在持续集成平台上测试 tkcalendar 时遇到了这个错误,因此下一版本的 tkcalendar (v1.5.0) 将通过设置回退语言环境来解决这个问题。但是现在您可以在创建 DateEntry 时显式传递语言环境以避免错误:

date_frame_container['date_picker'] = DateEntry(date_frame_container['frame']), locale='en_US')