>> ПРЕДПОСЫЛКИ:
Я хочу обновить/изменить текст кнопки на втором экране нажатием кнопки на главном экране. Что ж, я провел небольшое исследование и сделал то, что хотел, и когда я проверил в терминале, текст действительно изменился. НО, текст, показанный на втором экране, этого не сделал.
>> ВОТ ЧТО Я СДЕЛАЛ:
((Имейте в виду, что я использую только фрагменты кода, например, я собираюсь опубликовать весь код ниже.))
Button:
text:"PRESS TO CHANGE TEXT"
on_press:
root.funcself()
## on press it goes to it's root and do the "funcself" function in it
который :
class MainScreen(Screen):
def funcself(self):
app.second.funcscreen()
## it re-directs to the SecondScreen and do the "funcscreen" function
который :
class SecondScreen(Screen):
def funcscreen(self):
self.ids["button"].text = "SUPPOSED TO CHANGE TO THIS"
а затем я проверил, успешно ли я это сделал, выполнив print(self.ids["button"].text)
, и да!
Он действительно изменился, но когда я перешел к следующему экрану, отображаемый текст все еще не изменился.
Есть желающие помочь и объяснить?
ПОЛНЫЙ КОД:
файл питона:
import kivy
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.label import Label
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivy.uix.screenmanager import ScreenManager, Screen
class MainScreen(Screen):
def funcself(self):
app.second.funcscreen()
class SecondScreen(Screen):
def funcscreen(self):
value = self.ids["button"]
self.ids["button"].text = "SUPPOSED TO CHANGE TO THIS"
kv = Builder.load_file("reproduce.kv")
class reproduce(App):
second = SecondScreen()
def build(self):
return kv
def change_screen(self, x):
scrnmngr = self.root.ids["sm"]
scrnmngr.current = x
def check(self):
print(self.second.ids["button"].text)
if __name__ == "__main__":
app = reproduce()
app.run()
киви файл:
<MainScreen>:
GridLayout:
rows:2
Label:
text: "PRESS TO GO TO THE NEXT PAGE"
GridLayout:
cols:2
Button:
text:"PRESS TO CHANGE TEXT"
on_press:
root.funcself()
Button:
text:">>>"
on_press:
app.change_screen("second")
root.manager.transition.direction = "left"
<SecondScreen>:
GridLayout:
rows:2
Label:
id:label
text: "PRESS TO CHECK AND RETURN TO PREV PAGE"
Button:
id:button
text:"TEXT BEFORE CHANGE"
on_press:
app.change_screen("first")
root.manager.transition.direction = "right"
app.check()
GridLayout:
cols: 1
ScreenManager:
id:sm
MainScreen:
id:main
name:"first"
SecondScreen:
id:second
name:"second"
Атрибут second
, который вы определяете в своем классе приложения, является новым экземпляром экрана, а не экземпляром, который вы получили в своем диспетчере экранов, который вы добавляете в kv. Вот почему, когда вы проверяете, вы видите, что он изменился, но не в правильном экземпляре. И снова, когда вы вызываете app.second.func с главного экрана, снова это неправильный экземпляр.
Но у вашего приложения всегда есть корень. В вашем случае это gridlayout. И у каждого экрана есть менеджер. Есть несколько способов получить к нему доступ. Но вы можете сделать так.
В вашем классе основного экрана в kv:
Button:
text:"PRESS TO CHANGE TEXT"
on_press:
root.manager.get_screen("second").ids["button"].text = "Something"
Здесь он получает screenmanager и использует свой метод get_screen()
, чтобы получить имя второго экрана, а затем идентификатор этого правила kv.
@flyynn нет проблем :)
Он не изменился, потому что есть два экземпляра SecondScreen()
, т. е. один экземпляр создан в файле kv, а другой — в классе приложения, reproduce()
. Представленное представление создается из файла kv, и второй экземпляр не имеет связанного с ним представления.
Есть два решения проблемы и удалить second = SecondScreen()
из класса App.
Each screen has by default a property manager that gives you the instance of the ScreenManager used.
class MainScreen(Screen):
def funcself(self):
self.manager.get_screen('second').funcscreen()
class MainScreen(Screen):
def funcself(self):
App.get_running_app().root.ids.second.funcscreen()
В следующем примере представлены два решения, но одно из них закомментировано.
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen
class MainScreen(Screen):
def funcself(self):
self.manager.get_screen('second').funcscreen()
# App.get_running_app().root.ids.second.funcscreen()
class SecondScreen(Screen):
def funcscreen(self):
value = self.ids["button"]
self.ids["button"].text = "SUPPOSED TO CHANGE TO THIS"
kv = Builder.load_file("reproduce.kv")
class reproduce(App):
def build(self):
return kv
def change_screen(self, x):
scrnmngr = self.root.ids["sm"]
scrnmngr.current = x
def check(self):
print(self.second.ids["button"].text)
if __name__ == "__main__":
reproduce().run()
спасибо за ответ на мой вопрос! особенно с предоставлением этого подробного ответа! Я очень благодарен за любую помощь, которую я могу получить.
Добро пожаловать в Stack Overflow. Добро пожаловать. Если вы хотите сказать «спасибо», проголосуйте за ответ этого человека или примите его.. Если вы принимаете чужой ответ: вы получаете +2 к репутации.
о, это имеет большой смысл! Большое спасибо за ответ на мой вопрос, ценю это, чувак.