我的.py和.kv文件中包含以下相關部分。引用.kv文件中的類屬性
class DrillScreen(Screen):
def __init__(self, **kwargs):
super(DrillScreen, self).__init__(**kwargs)
self.thedrill = drill(kwargs['options'])
self.thedrill.bind(on_answer = self.printtest)
def printtest(self,*args):
self.ids.answerlabel.text = self.thedrill.answer
print(self.ids.answerlabel.text)
def startdrill(self):
Process(target=self.thedrill.run).start()
<DrillScreen>:
FloatLayout:
FloatLayout:
size_hint: 1.0, None
height: self.width
pos_hint: {'center_x':0.5,'center_y':0.5}
id: wheelbox
background_color: 1,1,1,1
pos: 0, 200
Label:
id: answerlabel
pos_hint: {'center_x':0.5, 'center_y':0.5}
text: root.thedrill.answer
Button:
text: 'Start'
size_hint: 0.5, 0.1
on_release: root.startdrill()
Button:
text: 'Back'
size_hint: 0.5, 0.1
pos_hint: {'x':0.5}
這給了我一個錯誤AttributeError: 'DrillScreen' object has no attribute 'thedrill'
。如果我將標籤文本中的root.thedrill.answer
更改爲某個文字字符串,它運行良好,並且從printtest()
的輸出中我看到它在內部發生更改,但其顯示不會更新。我想要從.kv文件訪問類屬性,或者從.py文件設置標籤顯示。謝謝。
編輯:在約阿夫Glazner的建議 出發,我嘗試添加一個按鈕,也結合printtest()
功能,看看發生了什麼事情,我很困惑地看到,從不同綁定呼叫產生不同的輸出。下面是從的.py修改後的類:
class DrillScreen(Screen):
answer = StringProperty('alo')
def __init__(self, **kwargs):
self.thedrill = drill(kwargs['options'])
self.thedrill.bind(on_answer = self.printtest)
super(DrillScreen, self).__init__(**kwargs)
self.answer = self.thedrill.answer
b = Button(text = 'Test',
size_hint = [0.1,0.1],
pos_hint = {'top':1,'right':1})
b.bind(on_release = self.printtest)
self.ids.wheelbox.add_widget(b)
def printtest(self,*args):
self.answer = self.thedrill.answer
print('This is printtest(): ', self.ids.answerlabel.text)
def startdrill(self):
Process(target=self.thedrill.run).start()
到.kv文件的唯一變化是,標籤文本點root.answer
。當我運行它(並點擊.kv中調用startdrill()
的按鈕)時,thedrill
定期發送它的on_answer
事件,並且我還單擊新創建的按鈕以手動調用printtest
,並在終端中產生此類輸出:
('This is printtest(): ', 'ti')
('This is printtest(): ', 're')
('This is printtest(): ', 'Default')
('This is printtest(): ', 'Default')
('This is printtest(): ', 'so')
('This is printtest(): ', 'Default')
('This is printtest(): ', 'le')
('This is printtest(): ', 'Default')
與音節的線是的thedrill
on_answer
調度的結果,並與「默認」的那些是從按鈕的點擊。我無法想象會有什麼影響差異。在檢查drill
類時,我認爲沒有理由立即恢復到以前的值(它實際上在.answer
的行後設置sleep(1)
並分派事件)。也許我錯過了一些東西,如果沒有更合理的解釋存在,我可以發佈代碼。
EDIT2: 這是一個可運行的示例。 的.kv文件:
<DrillScreen>:
FloatLayout:
FloatLayout:
id: wheelbox
size_hint: 1.0, None
height: self.width
pos_hint: {'center_x':0.5,'center_y':0.5}
background_color: 1,1,1,1
pos: 0, 200
Label:
id: answerlabel
pos_hint: {'center_x':0.5, 'center_y':0.5}
text: root.answer
Button:
text: 'Start'
size_hint: 0.5, 0.1
on_release: root.startdrill()
和的.py:
from kivy.app import App
from random import choice
from time import sleep
from kivy.event import EventDispatcher
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.button import Button
from kivy.properties import StringProperty
from multiprocessing import Process
class DrillScreen(Screen):
answer = StringProperty('Initialized.')
def __init__(self, **kwargs):
self.thedrill = drill()
self.thedrill.bind(on_answer = self.printtest)
super(DrillScreen, self).__init__(**kwargs)
self.answer = self.thedrill.answer
b = Button(
text = 'printtest()',
size_hint = [ 0.1, 0.1 ],
pos_hint = {'center_x':0.75,'center_y':0.5},
)
b.bind(on_release = self.printtest)
print(self.ids)
self.ids.wheelbox.add_widget(b)
def printtest(self,*args):
self.answer = self.thedrill.answer
print('This is printtest(): ', self.ids.answerlabel.text)
def startdrill(self):
Process(target=self.thedrill.run).start()
class drill(EventDispatcher):
def __init__(self):
self.register_event_type('on_answer')
self.answer = 'Default'
def on_answer(self,*args):
pass
def run(self):
while True:
self.answer = str(choice(range(100)))
self.dispatch('on_answer', self.answer)
sleep(1)
class Manager(ScreenManager):
pass
class TestingApp(App):
def build(self):
sm = Manager()
s = DrillScreen(name='ds')
sm.add_widget(s)
sm.current = 'ds'
return sm
TestingApp().run()
點擊開始按鈕開始thedrill.run在自己的進程,隨地吐痰的隨機數到終端每一秒,而它正在運行,單擊printtest()按鈕輸出「Default」作爲標籤文本值。輸出示例:
('This is printtest(): ', '8')
('This is printtest(): ', '60')
('This is printtest(): ', '6')
('This is printtest(): ', 'Default')
('This is printtest(): ', '66')
('This is printtest(): ', '68')
('This is printtest(): ', 'Default')
('This is printtest(): ', '89')
('This is printtest(): ', '69')
的'沒有attribute'抱怨走了,但在外觀上依然標籤甚至不更新時'printtest() '語句向終端輸出正確的值。我也嘗試使用'answer = StringProperty('')',直接爲'root.answer'標籤和'printtest'定義設置'self.answer'。它只是開始與我初始化「答案」,並永遠不會改變。另外,如果我將它初始化爲'def __init__'前面的'test',但在'super'之前設置'self.answer = self.thedrill.answer',它會被正確設置。 'printtest'內的相同語句失敗。 – kuoytfouy
可能需要一個小的運行示例來查看這個... –
Galazner我包括一個。我懷疑這與'drrill.run'運行在一個單獨的過程中有關,但我不能勝任,以弄清楚如何。 – kuoytfouy