Текст кнопки не обновляется - PullRequest
2 голосов
/ 30 мая 2019

>> ФОН:

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

>> ЭТО ТО, ЧТО Я СДЕЛАЛ:

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

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), и да!Это изменилось, но когда я перешел к следующему экрану, показанный текст все еще не изменился.

Кто-нибудь может помочь и объяснить?

ПОЛНЫЙ КОД:

  • Python файл:

    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"
    

Ответы [ 2 ]

0 голосов
/ 30 мая 2019

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

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

Решение

Существует два решения проблемы, и удалите second = SecondScreen() изКласс приложения.

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

Каждый экран по умолчанию имеет менеджер свойств, который предоставляет вам экземпляр ScreenManager используется.

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

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

Использование App.get_running_app () & ids

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

0 голосов
/ 30 мая 2019

Атрибут second, который вы определяете в своем классе приложения, является новым экземпляром экрана, а не экземпляром, который вы получили в вашем менеджере экрана, который вы добавляете в kv. Вот почему, когда вы проверяете, вы видите, что оно изменилось, но не в нужном случае. И снова, когда вы вызываете app.second.func из mainscreen, снова это неправильный экземпляр.

Но у вашего приложения всегда есть рут. В вашем случае это gridlayout. И на каждом экране есть менеджер. Есть несколько способов получить к нему доступ. Но вы можете сделать это так.

В вашем классе главного экрана в кв:

Button:
    text:"PRESS TO CHANGE TEXT"
    on_press:
        root.manager.get_screen("second").ids["button"].text = "Something"    

Здесь он получает менеджер экрана и использует свой метод get_screen(), чтобы получить экран с именем second, а затем идентификаторы этого правила kv.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...