AttributeError:'NoneType'对象没有属性'ids'(self.root返回'None')

时间:2015-01-08 03:36:21

标签: python kivy

我试图从我的.py文件中访问.kv文件中由其ID定义的按钮/标签,并更改其“text”值。 所以我在构建函数中写道:

#self.root.ids.button.text='newValue'

它说AttributeError: 'NoneType' object has no attribute 'ids' 我尝试过很多方法从我班上的其他地方访问'self.root',但是没有一种方法可以工作。

我想知道为什么我班上没有自我根源?

这是我的kv档案:

<MyRun>:

    BoxLayout:
        id:bx1
        orientation: 'vertical'
        spacing: 10
        padding: [20]
        canvas:
            Color:
                rgba: .6, .6, .6, .3
            Rectangle:
                size: root.size
                source: 'pic\germanFlag.png'

        ActionBar:
            ActionView:
                id: av
                ActionPrevious:
                    with_previous: False
                    title: 'DeutschLerne' 
        Label:
            id:qtitle
            text: 'Percentage of Question Answered:{}%'.format(int(7))
            font_size: '30sp'
            size_hint_y: None
            height: '48dp'

        Label:
            id:qbody
            text: 'The answer is '+('{}'.format(str("Richtig!")) if 1>0 else '{}'.format(str("Falsch!")))
            color: [.3, 1, .5, 1] if 1>0 else [1, .2, .3, 1]
            font_size: '30sp'
            size_hint_y: None
            height: '48dp'

        Widget:
            canvas:
                Color:
                    rgba: .6 , .6 , .6 , .3
                Rectangle:
                    source: "pic\questionCanvas.png"
                    size: [self.width,self.height*3]
                    pos: [self.x,self.y-300]


        BoxLayout:
            id:bx2
            spacing: 10
            padding: [10, 200 , 10 , 0]

            Button:
                id:selA
                text: 'A'
                size_hint_y: None
                size_hint_x: .5
                on_release: app.answer(self.text)
                on_release: app.disableButton(self)
            Button:
                id:selB
                text: 'B'
                size_hint_y: None
                size_hint_x: .5 
                on_release: app.answer(self.text)
                on_release: app.disableButton(self)
            Button:
                id:selC
                text: 'C'
                size_hint_y: None
                size_hint_x: .5
                on_release: app.answer(self.text)
                on_release: app.disableButton(self)
            Button:
                id:selD
                text: 'D'
                size_hint_y: None
                size_hint_x: .5
                on_release: app.answer(self.text)
                on_release: app.disableButton(self)
                #on_release: app.go_screen(0)

        ProgressBar:
            id: pb
            size_hint_x: 1
            size_hint_y: None
            height: '48dp'
            value: (app.time * 20) % 100.

这是我的主要课程,Desutsch.py​​

from time import time
from kivy.app import App
from os.path import dirname, join
from kivy.properties import NumericProperty, StringProperty, BooleanProperty,\
    ListProperty,OptionProperty
from kivy.clock import Clock
from kivy.animation import Animation
from kivy.uix.screenmanager import Screen
from kivy.uix.gridlayout import GridLayout
from kivy.lang import Builder
from functools import partial
from kivy.uix.boxlayout import BoxLayout
from kivy.app import App
import random
NUM_OF_NOUN = 416       #constant . don't change its value
class MyRun(BoxLayout):
    pass
class DeutschApp(App):
    index = NumericProperty(-1)     
    challenges = NumericProperty(0)
    time = NumericProperty(0)
    wl = ListProperty([])
    len = 0                         

    ans = []            #.[0] => answer [1:3]
    ansID=[]            #.[0] => answer [1:3]
    order=[]            #random list(1~4)

    def build(self):
        Builder.load_file('Question.kv')
        self.title = 'Destsch Lernen'
        Clock.schedule_interval(self._update_clock, 1 / 60.)

        self.screens = {}
        self.available_screens = sorted([
            'Menu','Question'])

        len = self.loadWordList('default.txt')
        self.question(len)
        self.root.ids.selA.text='newValue'
        return MyRun()

    def go_screen(self, idx):
        self.index = idx
        self.root.ids.sm.switch_to(load_screen(idx), direction='left')

    def load_screen(self, index):
        if(0==index):
            screen = Builder.load_file('Question.kv')
        if(1==index):
            screen = Builder.load_file('Menu.kv')
        self.screens[index] = screen
        return screen
    #load question from local file

    def loadWordList(self,WordList):
        fd = open (WordList,'r')
        fd.readline()
        for line in fd:
            #line.split("|"):id|german|translation|[sentence1^^sen2^^]|hisCount|dailyCount|percentage
            line = line.rstrip("\n")
            tmp  = line.split('|')
            tmp[3] = tmp[3].replace("[", "")
            tmp[3] = tmp[3].replace("]", "")
            sen = tmp[3].split('^^')
            self.wl.append({'id': int(tmp[0]), 'german': tmp[1],'translation': tmp[2], 'sentences': sen, 'hisCount': int(tmp[4]), 'dailyCount':  int(tmp[5]), 'percentage':int(tmp[-1]) })
            #sentence encode not good
            print tmp[0]
            self.len = int(tmp[0])  #self.len = self.len+1
        print self.len
        self.question(self.len)
        return self.len

    def question(self,len):
        x = random.randint(0,len)
        ans = self.ans
        ansID = self.ansID

    #id0~416 =nouns  #Nouns self.wl[x].get('german')
        if x in range(0,NUM_OF_NOUN+1):                     
            qType = 0   #0=def , 1=senten 2=pic qType= random.randint(0,2)

            if (0==qType):
                ans.append({'id':x , 'sel':self.wl[x].get('translation')})
                ansID.append( int(x) )
                for all in range(0,3):
                    y = random.randint(0,NUM_OF_NOUN+1)
                    while( (y in ansID) or (y not in range(0,NUM_OF_NOUN+1)) ):
                        y = random.randint(0,NUM_OF_NOUN+1)
                    ans.append({'id':y , 'sel':self.wl[y].get('translation')})
                    ansID.append( int(y) )
                print ans               
            #elif:
            #else:

            #assign selections to buttons randomly
            order = self.RandomSelList
            print order



    def RandomSelList(self):
        a = random.sample(range(4), 4)
        return a

    def checkAnswer(self,ansList,choice):
        right = 0
        print "++"
        print ansList
        print choice
        return right

    def answer(self,choice):
        #print self.order[0]
        self.checkAnswer(self.ans,choice)
        print 'answer(%s)'%choice

    def Test(len):
        print random.randint(0,len)

    def _update_clock(self, dt):
        self.time = time()
#modify screen
    def selChange(self,button,sel):
        print 'selChange()'
        print self
        print self.root
        print super
        #self.root.ids.button.text='sel'

    def disableButton(self,button):
        button.disabled = True

    print super
    #Clock.schedule_interval(Test(len), 1)
if __name__=='__main__':
    DeutschApp().run()

我是新来的。对不起,丑陋的代码。我还在学习如何提出一个好问题。

1 个答案:

答案 0 :(得分:1)

root属性设置为从构建方法返回的任何内容,因此当您尝试访问它时它不存在(或者具体地说,默认值为None)。

你不需要它,因为无论如何你都有对小部件的引用。您可以将构建方法的结尾更改为

root = MyRun()
root.ids.selA.text='newValue'
return root