在Linux上它运行良好,但在android中它崩溃了。 输出(调试):
06-12 13:47:58.685 14524-14564/com.durov.maksim.learnenglish I/python: Traceback (most recent call last):
06-12 13:47:58.686 14524-14564/com.durov.maksim.learnenglish I/python: File "main.py", line 112, in <module>
06-12 13:47:58.687 14524-14564/com.durov.maksim.learnenglish I/python: MainApp().run()
06-12 13:47:58.688 14524-14564/com.durov.maksim.learnenglish I/python: File "/data/user/0/com.durov.maksim.learnenglish/files/app/crystax_python/site-packages/kivy/app.py", line 801, in run
06-12 13:47:58.691 14524-14564/com.durov.maksim.learnenglish I/python: self.load_kv(filename=self.kv_file)
06-12 13:47:58.692 14524-14564/com.durov.maksim.learnenglish I/python: File "/data/user/0/com.durov.maksim.learnenglish/files/app/crystax_python/site-packages/kivy/app.py", line 598, in load_kv
06-12 13:47:58.695 14524-14564/com.durov.maksim.learnenglish I/python: root = Builder.load_file(rfilename)
File "/data/user/0/com.durov.maksim.learnenglish/files/app/crystax_python/site-packages/kivy/lang/builder.py", line 290, in load_file
06-12 13:47:58.697 14524-14564/com.durov.maksim.learnenglish I/python: data = fd.read()
06-12 13:47:58.698 14524-14564/com.durov.maksim.learnenglish I/python: File "/data/user/0/com.durov.maksim.learnenglish/files/app/crystax_python/stdlib.zip/encodings/ascii.py", line 26, in decode
06-12 13:47:58.699 14524-14564/com.durov.maksim.learnenglish I/python: UnicodeDecodeError: 'ascii' codec can't decode byte 0xd0 in position 2145: ordinal not in range(128)
06-12 13:47:58.833 14524-14564/com.durov.maksim.learnenglish I/python: Python for android ended.
06-12 13:47:58.862 14524-14524/com.durov.maksim.learnenglish A/libc: Fatal signal 11 (SIGSEGV), code 1, fault addr 0x0 in tid 14524 (im.learnenglish)
main.py
#! /usr/bin/env python3
# -*- coding: utf-8 -*-
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.gridlayout import GridLayout
from kivy.config import ConfigParser
from custom_class import SettingScrollOptions, SettingsWithNoMenuAndBackButton
from utils import get_strings
from level_creator import Level
__version__= '0.1'
strings = get_strings("English")
def get_string(key):
return strings[key]
mode = 8
###################SCREENS##########################
class StartScreen(Screen):
level = None
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.create_level()
def show_hint(self):
pass
def create_level(self):
self.level = Level(mode, 1)
self.ids.game_grid.clear_widgets()
labels = self.level.get_letters_label()
self.ids.start_screen_top_label.text = MainApp.get_string(self, "found")+" " + self.level.get_words_found_count()
for f in range(len(labels)):
self.ids.game_grid.add_widget(labels[f])
pass
def on_touch_up(self, touch):
if not self.level.check_word():
self.level.unmark_position()
else:
self.ids.start_screen_top_label.text = MainApp.get_string(self, "found")+" " + self.level.get_words_found_count()
return super(StartScreen, self).on_touch_up(touch)
class ProgressScreen(Screen):
pass
class AboutScreen(Screen):
pass
class SetScreen(Screen):
def __init__(self, **kwargs):
super().__init__(**kwargs)
#self.add_widget(settings_panel)
pass
pass
class MenuScreen(Screen):
pass
class GameGrid(GridLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
pass
class MainApp(App):
height = 50
width = 50
global strings
def get_string(self, key):
return get_string(key)
def build(self):
sm = ScreenManager()
sm.add_widget(MenuScreen(name="Menu"))
sm.add_widget(SetScreen(name="Settings"))
sm.add_widget(AboutScreen(name="About"))
sm.add_widget(ProgressScreen(name="Progress"))
sm.add_widget(StartScreen(name="Start"))
return sm
if __name__ == "__main__":
MainApp().run()
main.kv
# File name: main.py
#: kivy 1.9.0
# -*- coding: utf-8 -*-
#:import Window kivy.core.window.Window
############################ Custom Widgets #########################
<GameGrid@GridLayout>:
size_hint: (None,None)
size: (Window.width,Window.width) if Window.width < Window.height else (Window.height,Window.height)
cols: 8
rows: 8
padding: 2
spacing: 1
canvas.before:
Color:
rgba: (.0,.6,.2,.8)
RoundedRectangle:
pos: self.pos
size: self.size
radius: [10,]
<MenuButton@Button>:
background_color: (0,0,0,0)
canvas.before:
Color:
rgba: (0,0,0,1)
RoundedRectangle:
pos: [self.pos[0],self.pos[1]-4]
size: [self.size[0]+4,self.size[1]+4]
radius: [50,]
Color:
rgba: (.41,.51,.94,1) if self.state=='normal' else (0,.7,.7,1)
RoundedRectangle:
pos: self.pos
size: self.size
radius: [50,]
markup: True
font_size : "25sp"
outline_color: (.1,.1,.1,1)
outline_width: 1
<BackgroundWithFlag@FloatLayout>:
FloatLayout:
canvas.before:
Rectangle:
pos: self.pos
size: self.size
source:"background.png"
padding: 80
<BackButton@Button>:
pos_hint: {'x':.01,'y':.92}
background_color: (0,0,0,0)
size_hint:(None,None)
size: (40,40)
canvas.before:
Rectangle:
pos: self.pos
size: self.size
source:"back_icon.png"
<HelpButton@BackButton>:
pos_hint: {'x':.875,'y':.92}
canvas.before:
Rectangle:
pos: self.pos
size: self.size
source:"help_icon.png"
########################## Screens ################################
<MenuScreen>:
BackgroundWithFlag:
BoxLayout:
padding: [40,40,40,40]
background_color: (.9,0,0,0)
orientation: "vertical"
spacing: 35
Label:
text: u"[b][i]Learn English[/i][/b]"
#text: u"[b][i]Изучение Английского[/i][/b]"
#font_size : 30
font_size : 40
markup: True
outline_color: (.1,.1,.1,1)
outline_width: 2
MenuButton:
text: u"[b]"+app.get_string("start_learn")+"[/b]"
on_press:
root.manager.transition.direction ='left'
root.manager.current='Start'
MenuButton:
text: u"[b]"+app.get_string("progress")+"[/b]"
on_press:
root.manager.transition.direction ='left'
root.manager.current='Progress'
MenuButton:
text: u"[b]"+app.get_string("settings")+"[/b]"
on_press:
#app.open_settings()
root.manager.transition.direction ='left'
root.manager.current='Settings'
MenuButton:
text: u"[b]"+app.get_string("about")+"[/b]"
on_press:
root.manager.transition.direction ='left'
root.manager.current='About'
<SetScreen>:
#on_enter: app.open_settings()
BackgroundWithFlag:
<AboutScreen>:
BackgroundWithFlag:
BackButton:
on_press:
root.manager.transition.direction = 'right'
root.manager.current='Menu'
<ProgressScreen>:
BackgroundWithFlag:
BackButton:
on_press:
root.manager.transition.direction = 'right'
root.manager.current='Menu'
<StartScreen>:
on_enter: root.create_level()
BackgroundWithFlag:
HelpButton:
on_press:
root.show_hint()
BackButton:
on_press:
root.manager.transition.direction = 'right'
root.manager.current='Menu'
AnchorLayout:
size_hint:(1,1.18)
anchor_x : 'center'
anchor_y : 'center'
GameGrid:
id: game_grid
#on_release: root.create_level()
Label:
canvas.before:
Color:
rgba: (.0,.5,.7,.8)
RoundedRectangle:
pos: self.pos
size: self.size
radius: [10,]
text: 'some basic word'
markup: True
font_size: '25sp'
size_hint:(1,.26)
pos_hint: {'x':0,'y':.005}
Label:
canvas.before:
Color:
rgba: (.0,.6,.2,.8)
RoundedRectangle:
pos: self.pos
size: self.size
radius: [10,]
id: start_screen_top_label
font_size: '18sp'
size_hint:(.72,.07)
pos_hint: {'x':.14,'y':.92}
level_creator.py
#! /usr/bin/env python
import random
import json
from kivy.uix.label import Label
from kivy.graphics import Color, RoundedRectangle
def check_position_in_list(position, mylist):
for i in mylist:
if position == i:
return True
return False
def check_word_not_in_use_words(check_word, all_words):
if len(all_words) == 0:
return True
for word in all_words:
if check_word["id"] == word["id"]:
return False
return True
buffer = []
class LetterLabel(Label):
can_mark = True
mark = False
position = -1
def __init__(self, position, **kwargs):
super().__init__(**kwargs)
self.font_size = "35sp"
self.position = position
pass
def mark_label(self):
self.canvas.before.clear()
if self.mark:
with self.canvas.before:
Color(0, 0, 1, 0.5)
RoundedRectangle(pos=self.pos, size=self.size, radius=[5, ])
else:
with self.canvas.before:
Color(0, 1, 0, 0.2)
RoundedRectangle(pos=self.pos, size=self.size, radius=[5, ])
pass
def on_size(self, *args):
self.canvas.before.clear()
with self.canvas.before:
Color(0, 1, 0, 0.2)
RoundedRectangle(pos=self.pos, size=self.size, radius=[5, ])
def on_touch_move(self, touch):
if self.collide_point(*touch.pos):
if not self.mark:
self.mark = True
self.mark_label()
global buffer
buffer.append(self.position)
return True
return super(LetterLabel, self).on_touch_move(touch)
class Level:
mode = 8
level_number = 1
level_words = []
letters_label = []
use_words = []
words_found_count = 0
def __init__(self, mode, level_number):
self.level_number = level_number
self.mode = mode
pass
def create_empty_letters_label(self):
for x in range(0, self.mode*self.mode):
self.letters_label.append(LetterLabel(x))
def get_letters_label(self):
self.letters_label = []
self.fill_letters_label()
return self.letters_label
def place_word(self, word):
direction_change = 0
position = []
direct = random.choice(["up", "down", "left", "right"])
first_position = random.randint(0, self.mode*self.mode-1)
if self.letters_label[first_position].text == "":
position.append(first_position)
if len(position) > 0:
while len(position) <= len(word["word"]) and direction_change < 2:
if direct == "right":
if position[-1]+1 < self.mode*self.mode-1\
and position[-1]//self.mode == (position[-1]+1)//self.mode\
and not check_position_in_list(position[-1]+1, position) \
and self.letters_label[position[-1] + 1].text == "":
# write position number to position
position.append(position[-1]+1)
else:
direct = random.choice(["up", "down"])
direction_change += 1
pass
elif direct == "left":
if position[-1] > 0\
and position[-1]//self.mode == (position[-1]-1)//self.mode\
and not check_position_in_list(position[-1]-1, position) \
and self.letters_label[position[-1]-1].text == "":
# in line above list out of range exception
# write position number to position
position.append(position[-1]-1)
else:
direct = random.choice(["up", "down"])
direction_change += 1
pass
elif direct == "down":
if position[-1]+self.mode < self.mode*self.mode \
and not check_position_in_list(position[-1]+self.mode, position)\
and self.letters_label[position[-1] + self.mode].text == "":
# write position number to position
position.append(position[-1] + self.mode)
else:
direct = random.choice(["right", "left"])
direction_change += 1
pass
elif direct == "up":
if position[-1]-self.mode > 0\
and not check_position_in_list(position[-1]-self.mode, position)\
and self.letters_label[position[-1] - self.mode].text == "":
# write position number to position
position.append(position[-1] - self.mode)
else:
direct = random.choice(["left", "right"])
direction_change += 1
pass
if len(position) == len(word["word"]):
#print(str(len(position))+":"+str(len(word["word"])))
word["place"] = position
for x in range(0, len(position)):
self.letters_label[position[x]].text = word["word"][x]
#word["place"].append(position[x])
self.use_words.append(word)
def fill_letters_label(self):
self.use_words = []
self.create_empty_letters_label()
if len(self.level_words) == 0:
self.load_level()
for x in range(0, 400):
word_number = random.randint(0, len(self.level_words)-1)
word = self.level_words[word_number]
if check_word_not_in_use_words(word, self.use_words):
self.place_word(word)
for y in range(0, self.mode * self.mode):
if self.letters_label[y].text == '':
self.letters_label[y].text = '*'
def save_level(self, level_number):
json_level_words = json.dumps(self.level_words, indent=4)
open("levels/level_" + str(level_number) + ".json", "w", encoding='utf8').write(json_level_words)
pass
def load_level(self):
self.level_words = json.load(open("levels/level_"+str(self.level_number)+".json", 'r', encoding='utf8'))
pass
def get_words_found_count(self):
return str(self.words_found_count)+"/"+str(len(self.use_words))
def check_word(self):
global buffer
for word in self.use_words:
if word["place"] == buffer:
self.words_found_count = self.words_found_count+1
buffer = []
return True
return False
pass
def unmark_position(self):
global buffer
print("Level words")
for word in self.use_words:
print(word["word"]+":"+str(word["place"]))
pass
#print(buffer)
for position in buffer:
self.letters_label[position].mark = False
self.letters_label[position].mark_label()
buffer = []
utils.py
#! /usr/bin/env python3
# -*- coding: utf-8 -*-
import json
def get_strings(language):
if language == "English":
return json.load(open("localization/strings_us.json", "r", encoding='utf8'))
elif language == "Русский":
return json.load(open("localization/strings_ru.json", "r", encoding='utf8'))
elif language == "Українська":
return json.load(open("localization/strings_ua.json", "r", encoding='utf8'))
正如我所看到的问题在于编码字符串?如果我错了,请纠正我。我怎么解决这个问题? 如果需要,我可以显示所有python和kivy文件。 谢谢。