Kivy编译错误" NoneType"对象没有属性" name"

时间:2015-10-23 13:34:11

标签: android python kivy buildozer

##### main.py #####
from kivy.app import App
from kivy.app import Widget

from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import NumericProperty, ObjectProperty, StringProperty, ListProperty, BooleanProperty


class MainScreen(Screen):
    def __init__(self,**kwargs):
        super(MainScreen,self).__init__(**kwargs) # implements the features of a GridLayout (the base class of MainScreen)

    def save(self):
        '''Saves the data from the input to a text file.
    It is bound to the save button'''
        status = self.ids.workout1.ids.status.active
        workout = self.ids.workout1.ids.workoutInput.text
        day = self.ids.workout1.ids.dayInput.text
        time = self.ids.workout1.ids.timeInput.text
        with open('workoutData.txt','a') as f:
            f.write('%s, %s, %s, %s\n' %(status, workout, day, time))

        return None

    def totalTime(self):
        '''This function doesn't do anything right now! Add code to compute the total exercise time, and document it in this string'''
        return None

class WorkoutLayout(BoxLayout):
    pass

class SecondScreen(Screen):
    pass

class AppScreenManager(ScreenManager):
    name = StringProperty('Num Num')   ### <----line 37
    def __init__(self,**kwargs):
        super(AppScreenManager,self).__init__(**kwargs)
        self.name = 'Num Num'          ### <----line 40


class WorkoutApp(App):
    def build(self):
        sm = AppScreenManager()
        print (sm.name)
#         sm.name="123"
        sm.add_widget(MainScreen(name='main'))
        sm.add_widget(SecondScreen(name='secondary'))
        return sm

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



# NOTE: running is diff on diff platforms
# python main.py
# kivy main.py

##### part of workout.kv #####
<MainScreen>:
    BoxLayout:
        orientation: 'vertical'
        BoxLayout:
            orientation: 'horizontal'
            Label:
                text: 'Workout'
                size_hint_x: 2/3.
            Label:
                text: 'Day'
                size_hint_x: 1/6.
            Label:
                text: 'Time'
                size_hint_x: 1/6.

        WorkoutLayout:
            id: workout1
        WorkoutLayout:
            id: workout2
        WorkoutLayout:
            id: workout3
        WorkoutLayout:
            id: workout4
        WorkoutLayout:
            id: workout5
        WorkoutLayout:
            id: workout6
        WorkoutLayout:
            id: workout7

        BoxLayout:
            orientation: 'horizontal'
            Button: 
                text: 'Save'
                on_press: root.save()
            Button:
                text: 'Next screen'
                on_press: root.manager.current = 'secondary'

<SecondScreen>:
    BoxLayout:
        orientation: 'vertical'
        Label:
            size_hint_y: 3/4.
            text: root.manager.name         ### <----line 45
#            text: 'Hello second screen!'   ### <----line 46
        Button:
            size_hint: (1/4.,1/4.)
            text: 'Back to main screen'
            on_press: root.manager.current = 'main'

<WorkoutLayout>:
    size_hint_x: 1
    orientation: 'horizontal'
    CheckBox:
        id: status
        size_hint_x: 1/8.
    TextInput:
        id: workoutInput
        size_hint_x: 5/8.
    TextInput:
        id: dayInput
        size_hint_x: 1/8.
    TextInput:
        id: timeInput
        size_hint_x: 1/8.

TextInput:
    multiline: False

这些在线修改了一些示例代码。当我编译时,它显示"NoneType" object has no attribute "name",我的kv文件中的第45行出错。我尝试在我的main.py中注释37或40行,但仍然遇到了同样的错误。

如果我在workout.kv第45行中注释并取消注释第46行,则可以编译代码,并且main.py中的第46行可以打印出&#34; NumNum&#34;,这意味着sm确实具有属性名称。

1 个答案:

答案 0 :(得分:0)

看起来像是时间问题。在构造SecondScreen对象期间执行kv文件中的逻辑,此时它的管理器&#34;物业尚未填充。由于它尚未填充,因此其值为&#34;无,&#34;并且NoneType没有名称属性。

现在,为什么manager属性的值为None?好吧,根据Kivy的文档,这个属性是在屏幕添加到经理时设置的。&#34;在初始化之后你只是做了什么。

因此,当你在main.py中打印出值时,管理员属性已经被填充,但是当你在初始化期间调用的.kv文件中执行它时,你就是&#39 ;你的房产中有一个NoneType。

你能做些什么? 好吧,一种方法是将.kv中的违规行更改为:

text: root.manager.name if root.manager else ""

这将在初始化期间处理manager属性为None,并且稍后更新manager属性时,text属性应自动更新。也许有更优雅的方式来做到这一点。