按钮文字无法更新

时间:2019-05-30 13:46:23

标签: python kivy

>>背景:

我想通过按主屏幕中的按钮来更新/更改SecondScreen中按钮的文本。好吧,我做了一些研究并且做了我想要做的,当我在终端中签到时,文本确实发生了变化。 BUUT,第二个屏幕上显示的文本没有。

>>这就是我要做的:

(((请记住,例如,我仅使用代码片段,我将在下面发布整个代码。))

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()
    
  • kivy文件:

    <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 :(得分:0)

您在应用程序类中定义的second属性是屏幕的新实例,并不是您在screenmanager中获得的实例,而是在kv中添加的。这就是为什么在检查时会看到它已更改,但在正确的实例上却看不到的原因。再次,当您从主屏幕调用app.second.func时,它再次是错误的实例。

但是您的应用程序始终具有根目录。在您的情况下,其网格布局。每个屏幕都有一个经理。有两种方法可以访问它。但是你可以这样做。

在主屏幕上的kv中:

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

在此获取屏幕管理器,并使用其get_screen()方法获取名为second的屏幕,然后获取该kv规则的ID。

答案 1 :(得分:0)

根本原因

它没有改变,因为有SecondScreen()的两个实例,即一个实例在kv文件中实例化,另一个实例在App类reproduce()中实例化。呈现的视图是根据kv文件创建的,第二个实例没有与之关联的视图。

解决方案

有两种解决方法,可以从App类中删除second = SecondScreen()

Kivy Screen » default property manager

  

每个屏幕默认都有一个属性管理器,可为您提供   的ScreenManager的实例。

使用get_screen()

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

使用App.get_running_app()和ID

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