Я разрабатываю многоплатформенное приложение для Linux и Windows 7. Все мои файлы сначала были написаны в Linux и закодированы как utf-8
, но когда я открываю этот же проект в Windows, файл kv
читается с использованием кодировки cp1252
. То же самое, кажется, не происходит с моими файлами .py
возможно, потому, что я использую python3.
Как следствие, символы Юникода, записанные в файле kv
, некорректно отображаются в приложении Kivy. Строка 'Título'
будет отображаться как TÃ-tulo
.
Мои настройки: Kivy = 1.9.1, Python = 3.4.4, Windows 7 x64 Home Premium.
Также мой питон был установлен с использованием Anaconda, но это, вероятно, не связано.
Напишите файл kv
закодированный с помощью utf-8
:
# test.kv
<myButton@Button>:
text: 'Título'
В интерпретаторе python или .py
script:
import kivy
from kivy.lang import Builder
from kivy.uix.button import Button
Builder.load_file('test.kv')
class myButton(Button):
pass
print( myButton().text == 'Título' ) # False
print( myButton().text.encode('cp1252').decode() == 'Título' ) # True
Мультиплатформенный обходной путь, который я нашел, заключался в следующем:
# test.kv
<myButton@Button>:
text: str(b'T\xc3\xadtulo'.decode())
К вашему сведению - немного более простой способ обойти это - использовать литералы Unicode:
<MyButton@Button>:
text: u'T\u00edtulo'
Спасибо, воспользуюсь этим =)
Для кого-то еще, использующего эту работу, если вы хотите найти escape-последовательность Unicode для своего символа Unicode, вы можете найти ее так:
>> hex( ord('ã') )
0xe3
>> u'\u00e3'
'ã'
Вы не думаете, что должен быть способ лучше? (слышит, как Хеттингер говорит ...)
заголовок #, в котором рассказывается, как следует обрабатывать символ Юникода?
Даже если этот трюк сработает ... из-за этого текст становится очень трудно читать, когда много символов Юникода ...
Это только ошибка Windows?
Что ж, это не рекомендуемый способ обработки кодировок, но вы можете его использовать. Он работал у меня в py2.7 с kivy 1.8.0, но мог работать даже с py3. Файлы, сохраненные как символы utf-8
, \u...
используются непосредственно как u'ä'
import sys
reload(sys)
sys.setdefaultencoding("utf-8")
Да @ChristianTremblay , это только ошибка Windows. Фактически это связано с тем, что кодировка Windows по умолчанию - cp1252, в результате чего Kivy читает файл .kv, как если бы он был закодирован таким образом. Возможно, решение, предложенное @KeyWeeUsr, действительно помогает, я этого не пробовал, но может быть чище, чем другой предложенный обходной путь.
Я согласен, хорошим решением было бы разрешить кодирование спецификации в файле .kv, как это делается в python:
# -*- coding: utf-8 -*-
<MyWidget>:
# ...
Что, если бы utf-8 был обязательным для файлов kv?
def load_file(self, filename, **kwargs):
'''Insert a file into the language builder and return the root widget
(if defined) of the kv file.
:parameters:
`rulesonly`: bool, defaults to False
If True, the Builder will raise an exception if you have a root
widget inside the definition.
'''
filename = resource_find(filename) or filename
if __debug__:
trace('Builder: load file %s' % filename)
with open(filename, 'r', encoding='utf-8') as fd:
kwargs['filename'] = filename
data = fd.read()
# remove bom ?
if PY2:
if data.startswith((codecs.BOM_UTF16_LE, codecs.BOM_UTF16_BE)):
raise ValueError('Unsupported UTF16 for kv files.')
if data.startswith((codecs.BOM_UTF32_LE, codecs.BOM_UTF32_BE)):
raise ValueError('Unsupported UTF32 for kv files.')
if data.startswith(codecs.BOM_UTF8):
data = data[len(codecs.BOM_UTF8):]
return self.load_string(data, **kwargs)
Это находится в строке 275 и выше kivy / lang / builder.py.
@ChristianTremblay , я думаю, это было бы не к лучшему. Некоторые пользователи могут по-прежнему использовать текстовые редакторы с кодировкой по умолчанию, отличной от utf-8, например кодировкой Windows по умолчанию cp1252. Мы должны найти решение для обоих.
Лучше всего было бы имитировать поведение Python:
Возникла проблема на Android:
An unanticipated UnicodeDecodeError occurred: 'ascii' codec can't decode byte 0xef in position 564: ordinal not in range(128)
Traceback (most recent call last):
File "./pages.py", line 21, in <module>
Builder.load_file('pages.kv')
File "/data/data/.../files/app/crystax_python/site-packages/kivy/lang/builder.py", line 290, in load_file
data = fd.read()
File "/data/data/.../files/app/crystax_python/stdlib.zip/encodings/ascii.py", line 26, in decode
return codecs.ascii_decode(input, self.errors)[0]
UnicodeDecodeError: 'ascii' codec can't decode byte 0xef in position 564: ordinal not in range(128)
((boggle)) Хотя, похоже, работает на моем Linux.
По умолчанию обязательно должен быть utf-8, хотя и не принудительно.
mixmastamyk У меня была точно такая же проблема.
Мое приложение работает нормально, но когда я создаю APK и запускаю его на своем телефоне Android, я получаю:
UnicodeDecodeError: кодек ascii не может декодировать байт 0xc3 в позиции 352: порядковый номер не в диапазоне (128)
Это потому, что в моем файле есть пара «É». Жаль, что я кодировал на python3, чтобы избежать подобных раздражающих вещей.
Верно. Похоже, что Builder.load_file()
должен по умолчанию использовать utf8 и / или иметь параметр кодировки. А пока сделал вот что:
with open(filename, encoding='utf8') as f:
Builder.load_string(f.read())
Обязательно отключите автоматическую загрузку для файла kv, иначе ошибка все равно будет выдаваться, и все будет выглядеть так, как будто это не сработало. Форма '\ u2026' также может работать, если это всего лишь один или два символа.
Умная идея. Спасибо!
Я попробую это.
Эта проблема была автоматически помечена как устаревшая, поскольку в последнее время не было активности. Он будет закрыт, если больше не будет активности. Спасибо за ваш вклад.
Как удобно, игнорируйте ошибки и позвольте им закрыться сами.
На самом деле мы выкапывали старые проблемы, чтобы отсортировать их, и никакая действительная проблема, требующая решения, не будет закрыта. Хотя такое отношение не помогает с мотивацией, необходимой для того, чтобы посвятить наши дни проекту.
Раздражает не отсутствие работы, а бот, который закрывает проигнорированные задачи. Возможно, потребуется одна или две строки кода для добавления параметра кодирования в load_file. Сам бы сделал это, но есть 70 невыполненных запросов на вытягивание.
В проекте с ограниченными кадрами не должно быть такого типа бота.
Я все еще рекомендую вам сделать этот запрос на перенос. Если это чистое и простое исправление, у него есть хорошие шансы на объединение.
У меня такая же проблема с kivy 1.10, мое приложение отлично работает на linux с python3 (python3 main.py), но когда я отлаживаю развертывание на моем телефоне Android, приложение вылетает: / очень раздражает, если вы хотите сделать что-то качественно
По-прежнему существует эта проблема с kivy 1.10.1 и python 3.6.6 в Windows 10. Текущий обходной путь не заключается в автоматической загрузке файла .kv. Переименуйте его во что-то, что не загружается по умолчанию, сохраните его в кодировке utf8 и сделайте, как показано в # 5154
from kivy.lang import Builder
with open('MyApp.renamed.kv', encoding='utf8') as f:
Builder.load_string(f.read())
Решение @carasuca у меня не работает
киви 1.10.1 питон 3.5.3 окна 7
такое же поведение в Windows 10 и Python 3.6.5
Тот же код отлично работает на osx и linux
РЕДАКТИРОВАТЬ: проблема в директиве языка #:include
kv
Решение @carasuca работает тогда и только тогда, когда у вас есть один файл kv и вы загружаете его с помощью Builder.load_string (f.read ()). Если этот kv использует #: include anotherfile.kv, этот файл загружается с неправильной кодировкой.
Решение 1.Сместите весь код kv в один файл
Решение 2:
for kvfile in ['file1.kv', 'file2.kv']:
with open(kvfile, encoding='utf8') as f:
Builder.load_string(f.read())
Ну, у меня была такая же ошибка со словами вроде «Número» или «veículo». Я пробовал со следующим кодом:
from kivy.lang import Builder
with open('myApp.kv', encoding='utf8') as f:
Builder.load_string(f.read())
Но у меня возникла проблема с этим. Когда я запустил приложение, я увидел, что две разные метки перекрываются.
Решение заключалось в том, чтобы сохранить файл kv в подкаталоге, а затем вызвать его с помощью open следующим образом:
with open('./kvfile/myApp.kv', encoding='utf-8') as f:
Builder.load_string(f.read())
Проблема была решена, потому что автозагрузка не находит файл kv в том же каталоге, что и main.py. Так что это не будет дублировать визуализацию.
@piontk Привет, я думал, что это будет мое спасение, но когда я попробую, он говорит, что «кодировка» не является допустимым параметром для «open». Почему? (Кроме того, извините, если это глупый вопрос, это мое первое приложение)
Хорошо, я знаю, что это не идеально, но если ни один из этих вариантов не работает для вас, вы можете установить желаемую строку в переменную в основном классе приложения в вашем файле .py, который имеет кодировку utf-8, а затем получить к ней доступ в вашем файле .kv.
#.py
class MainApp(App):
struser = ('Nome de usuário')
#.kv
Label:
text: app.struser
работал на меня
Самый полезный комментарий
Да @ChristianTremblay , это только ошибка Windows. Фактически это связано с тем, что кодировка Windows по умолчанию - cp1252, в результате чего Kivy читает файл .kv, как если бы он был закодирован таким образом. Возможно, решение, предложенное @KeyWeeUsr, действительно помогает, я этого не пробовал, но может быть чище, чем другой предложенный обходной путь.
Я согласен, хорошим решением было бы разрешить кодирование спецификации в файле .kv, как это делается в python: