Kivy应用程序在Android上崩溃

时间:2018-06-12 11:03:38

标签: python kivy

在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文件。 谢谢。

0 个答案:

没有答案