【问题标题】:How to make a file chooser in kivy to support files with different languages (English, Hebrew)如何在 kivy 中制作文件选择器以支持不同语言的文件(英语、希伯来语)
【发布时间】:2019-01-29 16:24:07
【问题描述】:

我正在使用 kivy 的文件选择器,当有一个带有希伯来名称的文件夹的文件时,它会打印出乱码... 如果可能的话,我想支持不同的语言。 试图更改文件选择器中的字体名称,对我不起作用。 你能帮我找出我做错了什么吗?

【问题讨论】:

  • 您在文件选择器中看到乱码,还是在打印所选文件路径时打印乱码?
  • 两者。目前我更倾向于修复用户体验,但我希望能够向用户显示正确的名称并能够获取它,以便我可以使用选定的文件

标签: python kivy kivy-language


【解决方案1】:

不仅仅是FileChooser - Kivy 中所有Label 实例都默认使用Roboto 字体,这似乎不支持Unicode 字符。尝试运行此代码:

from kivy.app import App
from kivy.uix.label import Label


class TestApp(App):
    def build(self):
        return Label(text="עִבְרִית‎")


if __name__ == '__main__':
    TestApp().run()

Kivy 附带有several fonts,其中之一是DejaVuSans。让我们使用它:

from kivy.app import App
from kivy.uix.label import Label


class TestApp(App):
    def build(self):
        return Label(text="עִבְרִית‎", font_name='DejaVuSans.ttf')


if __name__ == '__main__':
    TestApp().run()

现在希伯来语显示正确。但是,它不适用于日语。对于该语言,您必须寻找另一种 Unicode 字体,将其放在目录中并传递给 font_name 属性。

无论如何。如何让FileChooser 使用不同的字体?最简单的方法是将方法绑定到on_entry_added 事件以更改目录树中新创建项目的属性:

from kivy.app import App
from kivy.clock import Clock
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout


Builder.load_string("""
<MyWidget>:
    FileChooserListView
        id: filechooser
""")

class MyWidget(BoxLayout):
    def __init__(self, *args):
        Clock.schedule_once(self.update_filechooser_font, 0)
        return super().__init__(*args)

    def update_filechooser_font(self, *args):
        fc = self.ids['filechooser']
        fc.bind(on_entry_added=self.update_file_list_entry)
        fc.bind(on_subentry_to_entry=self.update_file_list_entry)    

    def update_file_list_entry(self, file_chooser, file_list_entry, *args):
        file_list_entry.ids['filename'].font_name = 'DejaVuSans.ttf'


class MyApp(App):
    def build(self):
        return MyWidget()


if __name__ == '__main__':
    MyApp().run()

【讨论】:

  • 哇,谢谢你这个好心的陌生人!如果可以的话,最后一件事,当我使用您的解决方案时,希伯来语文本是颠倒的(希伯来语是从右到左书写的,而 kivy 从左到右显示它)您知道快速解决方法吗?
  • 您可以使用file_list_entry.ids['filename'].halign = 'right' 将文件名向右对齐,但您需要先检测它是否实际上是希伯来语。谷歌说你可以像this
  • halign 不起作用,因为它只是将反转的希伯来语文本移动到右侧。但是在您的帮助和您发送的链接的帮助下,我为此做了一个工作脚本。非常感谢,我正在上传我的解决方案作为新答案
  • @YotamHammer,我做了一些测试,还有一件事:除了绑定 on_entry_added 事件之外,您还应该将相同的函数绑定到 on_subentry_to_entry 事件,否则更改只会传播到顶级目录.我更新了答案中的代码。
  • 是的,我也看到了,后来添加了。谢谢我的程序员朋友
【解决方案2】:

这是我的解决方案。一半的功劳归于 Nykakin:

from kivy.app import App
from kivy.clock import Clock
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout


Builder.load_string("""
<MyWidget>:
    FileChooserListView
        id: filechooser
""")

class MyWidget(BoxLayout):
    def __init__(self, *args):
        Clock.schedule_once(self.update_filechooser_font, 0)
        return super(MyWidget, self).__init__(*args)

    def update_filechooser_font(self, *args):
        fc = self.ids.filechooser
        fc.bind(on_entry_added=self.update_file_list_entry)
        fc.bind(on_subentry_to_entry=self.update_file_list_entry)    


    def update_file_list_entry(self, file_chooser, file_list_entry, *args):
        file_list_entry.ids.filename.font_name = 'DejaVuSans.ttf'

        updated_text = []
        # to count where to insert the english letters
        english_counter = 0

        # the next statements used to split the name to name, extention
        splitted = file_list_entry.ids.filename.text.split('.')
        extention = ''
        if len(splitted) > 2:
            name = '.'.join(splitted)
        elif len(splitted) == 2:
            name = splitted[0]
            extention = splitted[1]
        else:
            name = '.'.join(splitted)

        # for each char in the reversed name (extention is always English and need to not be reversed)
        for char in name[::-1]:
            # if its in Hebrew append it regularly (reversed) and make sure to zero the counter
            if u"\u0590" <= char <= u"\u05EA":
                updated_text.append(char)
                english_counter = 0
            # if its an English character append it before the last english word (to un-reverse it) and increase the counter
            else:
                updated_text.insert(len(updated_text) - english_counter, char)
                english_counter += 1

        # add the extention in the end if exists
        if extention == '':
            file_list_entry.ids.filename.text = ''.join(updated_text)
        else:
            file_list_entry.ids.filename.text = ''.join(updated_text) + '.' + extention


class MyApp(App):
    def build(self):
        return MyWidget()


if __name__ == '__main__':
    MyApp().run()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-21
    • 2016-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-08
    • 1970-01-01
    • 2016-03-19
    相关资源
    最近更新 更多