У меня есть несколько кнопок, если я нажму кнопку - тогда экран изменится, и на новом экране появится метка, которая показывает текст, который был на кнопке, которая была нажата.
Это не работает, когда все выглядит правильно.
Python
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
from kivy.lang import Builder
from kivy.uix.button import Button
class ScreenOne(Screen):
pass
class ScreenTwo(Screen):
def on_pre_enter(self, *args):
btn = Button(text = "word is here", on_release =self.pressedFunction)
self.ids.container.add_widget(btn)
btn1 = Button(text = "another word is here", on_release =self.pressedFunction)
self.ids.container.add_widget(btn1)
def pressedFunction(self, instance, *args):
self.manager.current= "three"
screenThree = ScreenThree()
text = str(instance.text)
screenThree.changing_label(text)
class ScreenThree(Screen):
def changing_label(self, text):
self.ids.my_label.text = text
class ScreenManagement(ScreenManager):
pass
presentation = Builder.load_file("example.kv")
class MainApp(App):
def build(self):
return presentation
if __name__ == "__main__":
MainApp().run()
Киви
ScreenManagement:
ScreenOne:
ScreenTwo:
ScreenThree:
<ScreenOne>:
BoxLayout:
Button:
text: "press me"
on_release: app.root.current = "two"
<ScreenTwo>:
name: "two"
BoxLayout:
id: container
<ScreenThree>:
name: "three"
BoxLayout:
id: labelContainer
Label:
text: ""
Выход
File "example.py", line 28, in changing_label
self.ids.my_label.text = text
File "kivy\properties.pyx", line 841, in kivy.properties.ObservableDict.__getattr__
AttributeError: 'super' object has no attribute '__getattr__'
"my_label" не существует в вашем файле .kv, добавьте идентификатор на ярлык, где вы хотите внести эти изменения.
<ScreenThree>:
name: "three"
BoxLayout:
id: labelContainer
Label:
id: my_label
text: ""
В файле kv отсутствует id: my_label
.
Заполнение my_label.text
производилось после переключения экрана, self.manager.current = "three"
.
ЭкранТри создается дважды. Первый экземпляр создается в файле kv с помощью ScreenThree:
(это эквивалент ScreenThree()
в коде Python). Второй экземпляр создается в коде Python, screenThree = ScreenThree()
.
Заполнение my_label.text
происходит во втором экземпляре / объекте, а не в первом экземпляре. Следовательно, ScreenThree является пустым / черным окном, потому что приложение использует представление в соответствии с файлом kv, то есть первым экземпляром ScreenThree.
Если вы добавите функцию id()
, она будет отображать разные ячейки памяти для экранов.
def pressedFunction(self, instance, *args):
self.manager.current = "three"
self.debug()
screenThree = ScreenThree()
print("screenThree = {0}, id(screenThree) = {1}".format(screenThree, id(screenThree)))
self.debug()
text = str(instance.text)
screenThree.changing_label(text)
def debug(self):
print("\ndebug:")
print("\tself.manager.screen_names = ", self.manager.screen_names)
print("\tself.manager.screens = ", self.manager.screens)
for x in self.manager.screens:
print("\t\tscreen = {0}, id(screen) = {1}".format(x, id(x)))
id: screen_two
в ScreenTwo:
. Это будет использоваться для ссылки на атрибуты / методы класса в ScreenTwo.app.root.current = "two"
на root.manager.current = "two"
, потому что каждый экран по умолчанию имеет свойство manager
.id: my_label
под Label:
from kivy.properties import StringProperty
text = StringProperty('')
, чтобы не было необходимости передавать параметры, а также инкапсуляцию.text = str(instance.text)
на self.text = str(instance.text)
.changing_label()
в метод on_pre_enter()
и удалите text
из списка аргументов.self.ids.my_label.text = text' with
self.ids.my_label.text = self.manager.ids.screen_two.text`return presentation
на return Builder.load_file("example.kv")
и удалите presentation = Builder.load_file("example.kv")
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.lang import Builder
from kivy.uix.button import Button
from kivy.properties import StringProperty
class ScreenOne(Screen):
pass
class ScreenTwo(Screen):
text = StringProperty('')
def on_pre_enter(self, *args):
print("\nScreenTwo.on_pre_enter:")
btn = Button(text = "word is here", on_release =self.pressedFunction)
self.ids.container.add_widget(btn)
btn1 = Button(text = "another word is here", on_release =self.pressedFunction)
self.ids.container.add_widget(btn1)
def pressedFunction(self, instance, *args):
self.text = str(instance.text) # populate before switching screen
self.manager.current = "three" # switch screen
class ScreenThree(Screen):
def on_pre_enter(self, *args):
self.ids.my_label.text = self.manager.ids.screen_two.text
class ScreenManagement(ScreenManager):
pass
class MainApp(App):
def build(self):
return Builder.load_file("example.kv")
if __name__ == "__main__":
MainApp().run()
#:kivy 1.11.0
ScreenManagement:
ScreenOne:
ScreenTwo:
id: screen_two
ScreenThree:
<ScreenOne>:
BoxLayout:
Button:
text: "press me"
on_release: root.manager.current = "two" # every screen has a default property manager
<ScreenTwo>:
name: "two"
BoxLayout:
id: container
<ScreenThree>:
name: "three"
BoxLayout:
id: labelContainer
Label:
id: my_label
text: ""