How to make a file chooser in kivy to support files with different languages (English, Hebrew)

懵懂的女人 提交于 2019-12-11 10:27:34

问题


I am using kivy's file chooser and when there is a file of a folder with an Hebrew name, it prints gibberish... I want to support different languages if possible. Tried to change the font name in the file chooser, didn't work for me. Can you help me find out what am I doing wrong?


回答1:


It's not only FileChooser - all instances of Label in Kivy use Roboto font as a default, which doesn't seem to support Unicode characters. Try running this code:

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()

There are several fonts shipped with Kivy, one of them is DejaVuSans. Let's use it:

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()

And now Hebrew is displayed correctly. It doesn't work for Japanese, though. For that language you have to look for another Unicode font, place it in the directory and pass to the font_name property.

Anyway. How to make FileChooser use a different font? The simplest way would be binding a method to on_entry_added event to change properties of a newly created item in the directory tree:

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()



回答2:


This is my solution. Half of the credit goes to 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()


来源:https://stackoverflow.com/questions/54425450/how-to-make-a-file-chooser-in-kivy-to-support-files-with-different-languages-en

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!