1

I have a problem updating a screen in Kivy.

I'm trying to make to make a login screen in Kivy, and I'd like to store all the information of the user in different variables so that an algorithm could parse them and give them a score, and assign them a place to go.

Basically it is: filling info----> algorithm calculates ----> go to room x.

My problem is that after the calculation, the "go to room" screen doesn't update, meaning that the name of the person and the room are the initial values.

Here is the simplified code:

Python:

class Manual_insert(Screen):

    name_x = StringProperty()   
    room = ""

    def update_info(self):
        name_x =  self.ids.full_name.text
        print name_x



class First_room(Screen):
        names = StringProperty(str(Manual_insert.name_x)+ ", your assigned room is: " + str(Manual_insert.room)) 

and the KIVY file:

<Manual_insert>:
     name: "manual"
    Label:
        TextInput:
            id: full_name
            text: "Full Name"
            pos: root.center_x - (self.size[0] * 0.5), root.top  * 0.75

    Button:
        text: "Calculate"
        on_release: app.root.current = "first"
        on_release: root.update_info()
        pos: root.center_x - (self.size[0] * 0.5) , root.top * 0.05
        background_color: [3,1,0.2,.9]

 <First_room>:
    name: 'first'
    Button:
         text: root.names
         on_release: app.root.current = "welcome"
         background_color: [1.78,3,2.91,0.8]
         font_size: 50

When I run this I get the name on the console but on the app screen I get:

<StringProperty name=>, your assigned room is: 

Thank you for everything and if I wasn't clear enough don't hesitate to tell me.

eyllanesc
  • 235,170
  • 19
  • 170
  • 241

1 Answers1

2

Solution

Please refer to the snippets and example for details.

kv file

  1. Add ids to each screen
  2. Under on_release event for Button (Calculate), invoke root.update_info() method before switching to the next screen.

Snippet

<ScreenManagement>:
    Manual_insert:
        id: manual_insert

    First_room:
        id: first_room

    Welcome:
        id: welcome

Python Code

  1. Add self to the StringProperty in class methods.
  2. Add manager.ids.manual_insert to access string attributes in class Manual_insert()

Snippet

class Manual_insert(Screen):

    name_x = StringProperty('')
    room = StringProperty('')

    def update_info(self):
        self.name_x = self.ids.full_name.text
        print(self.name_x)


class First_room(Screen):
    names = StringProperty('')

    def on_pre_enter(self, *args):
        self.names = self.manager.ids.manual_insert.name_x + ", your assigned room is: " + self.manager.ids.manual_insert.room

Screen default property manager

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

ScreenManager Events

Events:

on_pre_enter: ()

Event fired when the screen is about to be used: the entering animation is started.

Example

main.py

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


class ScreenManagement(ScreenManager):
    pass


class Manual_insert(Screen):

    name_x = StringProperty('')
    room = StringProperty('')

    def update_info(self):
        self.name_x = self.ids.full_name.text
        print(self.name_x)


class First_room(Screen):
    names = StringProperty('')

    def on_pre_enter(self, *args):
        self.names = self.manager.ids.manual_insert.name_x + ", your assigned room is: " + self.manager.ids.manual_insert.room


class Welcome(Screen):
    pass


class TestApp(App):
    def build(self):
        return ScreenManagement()


if __name__ == "__main__":
    TestApp().run()

test.kv

#:kivy 1.11.0

<ScreenManagement>:
    Manual_insert:
        id: manual_insert

    First_room:
        id: first_room

    Welcome:
        id: welcome

<Manual_insert>:
    name: "manual"
    BoxLayout:
        Label:
            text: "Full Name"
        TextInput:
            id: full_name
            pos: root.center_x - (self.size[0] * 0.5), root.top  * 0.75

        Button:
            text: "Calculate"
            pos: root.center_x - (self.size[0] * 0.5) , root.top * 0.05
            background_color: [3,1,0.2,.9]
            on_release:
                root.update_info()
                root.manager.current = "first"

<First_room>:
    name: 'first'
    Button:
        text: root.names
        on_release: root.manager.current = "welcome"
        background_color: [1.78,3,2.91,0.8]
        font_size: 50

<Welcome>:
    Label:
        text: 'Welcome!'

Output

Img01

ikolim
  • 15,721
  • 2
  • 19
  • 29
  • Ikolim Thank you so much! A little thing: on_pre_enter didn't work properly because the initial text would only appear on the second time you fill the form. Instead I just used on_enter, and it works just fine! Really appreciated! – PaturonChimere Jul 27 '18 at 12:49
  • @PaturonChimere: In your kv file, under `on_release` event for *Button (Calculate)*, you have to invoke `root.update_info()` method before switching screen. Please remember to vote on and/or mark the answer as accepted, eh! Thank you. – ikolim Jul 27 '18 at 15:02