Kivy:修改另一个单独的子部件 class
Kivy: Modifying a child widget of another separate class
我目前正在研究 kivy 以开始跨平台开发。我有一点 python 经验(但很基础),现在想在 kivy 中编写一个小游戏来进入。我可能不会完成这个,但我喜欢在做我感兴趣的事情的同时学习东西。
无论如何,我的 "App" 应该被分成两个单独的 "screens",上面的一个仅用于显示内容,所有交互内容都由底部 "screen" 控制。
现在我想以旧学校的方式显示一些文本,将它一个字母一个字母地写到屏幕上。
这工作正常但出于某种原因,如果我从顶部屏幕调用 "print_something" 函数,Label 小部件仅在屏幕上更新,如果我从底部屏幕调用它,该函数确实被调用但 Label 小部件不会改变在屏幕上。
难道我做错了什么?
这是代码的精简版:
from kivy.app import App
from kivy.lang import Builder
from kivy.properties import ObjectProperty
from kivy.core.window import Window
from kivy.uix.widget import Widget
from kivy.clock import Clock
Builder.load_string('''
<MainUI>:
orientation: 'vertical'
# both these variables can be the same name and this doesn't lead to
# an issue with uniqueness as the id is only accessible in kv.
<Screen1>:
print_txt: print_txt
layout: layout
RelativeLayout:
id: layout
pos: 0, 400
size: 480, 400
Button:
pos: 0, 200
size_hint: (1, 0.2)
text: "Test Print"
on_press: root.print_something('TEST PRINT FROM SCREEN1')
AnchorLayout:
anchor_x: 'center'
anchor_y: 'bottom'
Label:
id: print_txt
padding_x: 10
markup: True
text_size: self.size
halign: 'left'
valign: 'top'
size_hint: (1, 0.2)
text: ""
<Screen2>:
btn1: btn1
RelativeLayout:
pos: 0, 0
size: 480, 400
Button:
id: btn1
pos_hint: {'x': .15, 'center_y': .5}
size_hint: (0.7, 0.5)
text: "Test Print"
on_press: root.print_text()
''')
class Screen1(Widget):
print_txt = ObjectProperty(None)
layout = ObjectProperty(None)
def print_something(self, string):
print 'Function called...'
self.print_txt.text = ''
counter = [0]
string_len = len(string)
def print_step(dt):
if counter[0] == string_len:
return False
else:
self.print_txt.text += string[counter[0]]
counter[0] = counter[0] + 1
Clock.schedule_interval(print_step, 2.0/60.0)
print 'Function End..'
class Screen2(Widget):
btn1 = ObjectProperty(None)
def __init__(self):
super(Screen2, self).__init__()
def print_text(self):
print 'Trying to print Text from Screen2 to Screen1'
target = Screen1()
target.print_something('TEST PRINT FROM SCREEN2')
class MainUI(Widget):
def __init__(self):
super(MainUI, self).__init__()
self.screen1 = Screen1()
self.add_widget(self.screen1)
self.add_widget(Screen2())
class MainApp(App):
def build(self):
Window.size = (480, 800)
return MainUI()
if __name__ == '__main__':
MainApp().run()
你的 Screen2 print_text 方法创建了一个 new Screen1 实例,它被修改但没有显示在任何地方,所以你看不到任何变化。
您可以将调用改为
on_press: root.parent.screen1.print_text()
...访问您实际要更新的 Screen1 实例的 print_text 函数。
我目前正在研究 kivy 以开始跨平台开发。我有一点 python 经验(但很基础),现在想在 kivy 中编写一个小游戏来进入。我可能不会完成这个,但我喜欢在做我感兴趣的事情的同时学习东西。 无论如何,我的 "App" 应该被分成两个单独的 "screens",上面的一个仅用于显示内容,所有交互内容都由底部 "screen" 控制。
现在我想以旧学校的方式显示一些文本,将它一个字母一个字母地写到屏幕上。 这工作正常但出于某种原因,如果我从顶部屏幕调用 "print_something" 函数,Label 小部件仅在屏幕上更新,如果我从底部屏幕调用它,该函数确实被调用但 Label 小部件不会改变在屏幕上。 难道我做错了什么?
这是代码的精简版:
from kivy.app import App
from kivy.lang import Builder
from kivy.properties import ObjectProperty
from kivy.core.window import Window
from kivy.uix.widget import Widget
from kivy.clock import Clock
Builder.load_string('''
<MainUI>:
orientation: 'vertical'
# both these variables can be the same name and this doesn't lead to
# an issue with uniqueness as the id is only accessible in kv.
<Screen1>:
print_txt: print_txt
layout: layout
RelativeLayout:
id: layout
pos: 0, 400
size: 480, 400
Button:
pos: 0, 200
size_hint: (1, 0.2)
text: "Test Print"
on_press: root.print_something('TEST PRINT FROM SCREEN1')
AnchorLayout:
anchor_x: 'center'
anchor_y: 'bottom'
Label:
id: print_txt
padding_x: 10
markup: True
text_size: self.size
halign: 'left'
valign: 'top'
size_hint: (1, 0.2)
text: ""
<Screen2>:
btn1: btn1
RelativeLayout:
pos: 0, 0
size: 480, 400
Button:
id: btn1
pos_hint: {'x': .15, 'center_y': .5}
size_hint: (0.7, 0.5)
text: "Test Print"
on_press: root.print_text()
''')
class Screen1(Widget):
print_txt = ObjectProperty(None)
layout = ObjectProperty(None)
def print_something(self, string):
print 'Function called...'
self.print_txt.text = ''
counter = [0]
string_len = len(string)
def print_step(dt):
if counter[0] == string_len:
return False
else:
self.print_txt.text += string[counter[0]]
counter[0] = counter[0] + 1
Clock.schedule_interval(print_step, 2.0/60.0)
print 'Function End..'
class Screen2(Widget):
btn1 = ObjectProperty(None)
def __init__(self):
super(Screen2, self).__init__()
def print_text(self):
print 'Trying to print Text from Screen2 to Screen1'
target = Screen1()
target.print_something('TEST PRINT FROM SCREEN2')
class MainUI(Widget):
def __init__(self):
super(MainUI, self).__init__()
self.screen1 = Screen1()
self.add_widget(self.screen1)
self.add_widget(Screen2())
class MainApp(App):
def build(self):
Window.size = (480, 800)
return MainUI()
if __name__ == '__main__':
MainApp().run()
你的 Screen2 print_text 方法创建了一个 new Screen1 实例,它被修改但没有显示在任何地方,所以你看不到任何变化。
您可以将调用改为
on_press: root.parent.screen1.print_text()
...访问您实际要更新的 Screen1 实例的 print_text 函数。