简体   繁体   中英

How to acess a variable from other class inside a def with kivy?

Problem

I'm using kivy and ScreenManager to do a GUI and use many screens.

I have a class Screen1, and one variable inside it, named num , which value is 1.

The Screen1 GUI has a button, and when I press the button, it calls a def calledwithbutton who changes the num variable to self.num = 2 , then changes the screen to Screen 2.

The Screen2 class has a variable var witch value is Screen1().num .

The Screen2 GUI has a label, witch text is str(var)

The expected result, is that Screen2 GUI label text = '2'

But the real result, is that Screen 2 GUI label text = '1'

How can I change the Screen 2 GUI label text to '2' , based on num variable?

.py code

from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen


class Manager(ScreenManager):
    pass

class Screen1(Screen):

    num = 1

    def calledwithbutton(self):

        self.num = 2
        self.parent.current = 'Screen 2'

class Screen2(Screen):

    var = Screen1.num

class RootApp(App):

    def build(self):
        return Manager()

RootApp().run()

.kv code

<Manager>:

    Screen1:
        name: 'Screen 1'

    Screen2:
        name: 'Screen 2'

<Screen1>:

    Button:
        text: 'This is a button'
        on_press: root.calledwithbutton()

<Screen2>:

    Label:
        text: str(root.var)

I believe you confuse objects and classes. A class is like a blueprint and a object is one instance that is made from that blueprint.

Classes themselves are usually not used to store information that is altered during the program run.

So if you take an object and modify it, it will not affect other objects. You need to safe the object you modified if you want to reuse it (or use a global variable which is very bad style, so you should not do this!).

Example:

class A:
    num = 5

A() #I create an object but do not safe it (since I do not assign a variable)
A().num = 6 #will only alter the object that I just made but never assigned to a variable
print(A().num) #I print a new object (that I just make) so no 6 but a 5
a=A() #I make a object
a.num = 7 #alter something
print(a.num) #the change is saved

a=A() #I overwrite the object
print(a.num) #the change is gone

For this type of tasks you do not have to use static variables since this one does not notify the change, in your case var only takes the value of num that is 1 when a Screen2 object is created, so it will never change to 2.

In kivy the solution for these cases is to use the properties , in this case NumericProperty, and then we make a binding between the properties.

*.py

from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import NumericProperty

class Manager(ScreenManager):
    pass

class Screen1(Screen):
    num = NumericProperty(1)

    def calledwithbutton(self):
        self.num = 2
        self.manager.current = 'Screen 2'

class Screen2(Screen):
    var = NumericProperty(0)

class RootApp(App):
    def build(self):
        return Manager()

if __name__ == '__main__':
    RootApp().run()

*.kv

<Manager>:
    Screen1:
        id: screen1
        name: 'Screen 1'
    Screen2:
        id: screen2
        name: 'Screen 2'
        var: screen1.num # binding

<Screen1>:
    Button:
        text: 'This is a button'
        on_press: root.calledwithbutton()

<Screen2>:
    Label:
        text: str(root.var)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM