Текст кнопки не обновляется

>> ПРЕДПОСЫЛКИ:

Я хочу обновить/изменить текст кнопки на втором экране нажатием кнопки на главном экране. Что ж, я провел небольшое исследование и сделал то, что хотел, и когда я проверил в терминале, текст действительно изменился. НО, текст, показанный на втором экране, этого не сделал.

>> ВОТ ЧТО Я СДЕЛАЛ:

((Имейте в виду, что я использую только фрагменты кода, например, я собираюсь опубликовать весь код ниже.))

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"
    
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
0
59
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Атрибут 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 30.05.2019 16:14

@flyynn нет проблем :)

el3ien 30.05.2019 16:14
Ответ принят как подходящий

Основная причина

Он не изменился, потому что есть два экземпляра SecondScreen(), т. е. один экземпляр создан в файле kv, а другой — в классе приложения, reproduce(). Представленное представление создается из файла kv, и второй экземпляр не имеет связанного с ним представления.

Решение

Есть два решения проблемы и удалить second = SecondScreen() из класса App.

Kivy Screen » менеджер свойств по умолчанию

Each screen has by default a property manager that gives you the instance of the ScreenManager used.

Использование get_screen()

class MainScreen(Screen):
    def funcself(self):
        self.manager.get_screen('second').funcscreen()

Использование App.get_running_app() и идентификаторов

class MainScreen(Screen):
    def funcself(self):
        App.get_running_app().root.ids.second.funcscreen()

Пример

В следующем примере представлены два решения, но одно из них закомментировано.

main.py

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()

Выход

Result

спасибо за ответ на мой вопрос! особенно с предоставлением этого подробного ответа! Я очень благодарен за любую помощь, которую я могу получить.

flyynn 30.05.2019 17:14

Другие вопросы по теме