Python 2.7 引用.kv文件中的类属性
我的.py和.kv文件中有以下相关部分Python 2.7 引用.kv文件中的类属性,python-2.7,kivy,Python 2.7,Kivy,我的.py和.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 pri
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()
对.kv文件的唯一更改是标签文本指向
root.answer
。当我运行此操作时,(并单击.kv中调用startdrill()
)的按钮,drill
定期发送其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')
带音节的行是对的回复的结果,带“Default”的行是点击按钮的结果。我无法想象会有什么影响。在检查钻取
类时,我看不出它有理由立即恢复到以前的值(它实际上在设置行之后的行上执行睡眠(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()
单击“开始”按钮将启动Drill.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')
您需要更改初始化函数中的顺序:
thedrill = ObjectProperty(None) # not really needed ...
def __init__(self, **kwargs):
self.thedrill = drill(kwargs['options'])
self.thedrill.bind(on_answer = self.printtest)
super(DrillScreen, self).__init__(**kwargs) # this will trigger the kv file section that exploded before ...
也就是说,使用进程将不适用于您的示例,因为每个进程都有自己的内存,无法直接处理UI。您应该使用进程队列或移动到线程。只需记住从主线程更新UI。(使用时钟或@mainthread)
玩得开心 没有属性
投诉消失,但即使printtest()
语句将正确的值打印到终端,外观上的标签也不会更新。我还尝试使用answer=StringProperty(“”)
,给出标签root.answer
,并直接在printest
定义设置self.answer
中使用。它只是从我初始化的答案开始,从不改变。另外,如果我将其初始化为,在def\uuuu init\uuuu
之前说“test”,但在super
之前将其设置为self.answer=self.drill.answer
。同样的语句在printtest
中失败。Galazner我包括一个。我怀疑这和退出有关。在一个单独的进程中运行,但我并没有足够的能力去弄清楚如何运行。是的。。。无法从其他进程更新UI。。。您必须通过队列/管道将数据传递给主线程/进程…事实证明,使用线程而不是多进程可以解决这个问题。如果你在编辑回答中提到这一点,我会接受。
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()
('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')
thedrill = ObjectProperty(None) # not really needed ...
def __init__(self, **kwargs):
self.thedrill = drill(kwargs['options'])
self.thedrill.bind(on_answer = self.printtest)
super(DrillScreen, self).__init__(**kwargs) # this will trigger the kv file section that exploded before ...