Search code examples
pythonkivykivy-language

Kivy: changed variables with Screen Manager


At first here my main.py Code:

import kivy

from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen, SlideTransition
from kivy.properties import ObjectProperty, ListProperty, StringProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.textinput import TextInput
from kivy.uix.popup import Popup
from kivy.core.window import Window
from random import *

class Boxlayout(BoxLayout):
    pass

class Textinput(TextInput):
    pass


class Variablen():
    Spielernamen = []
    Beginner = 0
    Zweiter = 0


    def get_names(self):
        Name1 = Namensabfrage.name_1.text
        Name2 = Namensabfrage.name_2.text
        self.Spielernamen.append(Name1)
        self.Spielernamen.append(Name2)
        print(Variablen.Spielernamen)



class Namensabfrage(Screen):
    name_1 = ObjectProperty()
    name_2 = ObjectProperty()


class Anzeige(Screen, Variablen):
    Spieler1 = str(Variablen.Spielernamen[0])
    Spieler2 = str(Variablen.Spielernamen[1])

class Manager(ScreenManager):

    namensabfrage = ObjectProperty(None)
    anzeige = ObjectProperty(None)

class ScreensApp(App):

    def build(self):
        m = Manager(transition=SlideTransition())
        return m


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

Then my Screen.kv file:

<Namensabfrage>:

    name_1: name1
    name_2: name2

    Boxlayout:
        orientation: 'vertical'
        padding: 50
        spacing: 50
        Label: 
            text: "gebt hier eure Namen ein"

        Textinput:
            id: name1
            size_hint: (1, .3)
            text: ""
            multiline: False 

        Textinput:
            id: name2
            size_hint: (1, .3)
            text: ""
            multiline: False 

        Button:
            text: "Bestätigen"
            size_hint:(1,.4)
            on_press: root.Variablen.get_names()

        Button: 
            size_hint: (1, .5)
            text: "Start"
            on_press: root.manager.current = "Screen2"



<Anzeige>:

    Boxlayout:
        orientation: 'vertical'
        spacing: 50

        Label: 
            text: root.Spieler1

        Label:
            text: root.Spieler2


<Manager>: 
    id: screen_manager

    namensabfrage: Namensabfrage
    anzeige: Anzeige


    Namensabfrage: 

        id: Namensabfrage
        name: "Screen1"
        manager: screen_manager

    Anzeige: 

        id: Anzeige
        name: "Screen2"
        manager: screen_manager

My Problem now is:

I want to display the Elements of the List "Spielernamen" in the Screen "Anzeige". But if i run the Programm it says that the list index is out of range. I know that the list index is out of range. But I want to add Names in this list with the function "get_names()". So first i want to get the names and then i want to display the names in another Screen.

How can i do this?

i hope you understand my Problem

Thank you in advance!!


Solution

  • Problem

    IndexError: list index out of range - Spieler1 = str(Variablen.Spielernamen[0])

    This error occurred because the list, Variablen.Spielernamen[0] is empty when the class was instantiated.

    Solution

    The fix for the IndexError, add a method on_pre_enter as shown:

    class Anzeige(Screen, Variablen):
    
        def on_pre_enter(self):
            Spieler1 = str(Variablen.Spielernamen[0])
            Spieler2 = str(Variablen.Spielernamen[1])
    

    Note

    As you fix the IndexError, there are more errors. Please refer to my example for the complete solutions to all the errors.

    Example

    main.py

    from kivy.app import App
    from kivy.uix.screenmanager import ScreenManager, Screen, SlideTransition
    from kivy.properties import ObjectProperty, ListProperty, StringProperty
    from kivy.uix.boxlayout import BoxLayout
    from kivy.uix.textinput import TextInput
    from kivy.uix.popup import Popup
    from kivy.core.window import Window
    from random import *
    
    
    class Boxlayout(BoxLayout):
        pass
    
    
    class Textinput(TextInput):
        pass
    
    
    class Variablen():
        Spielernamen = []
        Beginner = 0
        Zweiter = 0
    
        def get_names(self, Namensabfrage):
            Name1 = Namensabfrage.name_1.text
            Name2 = Namensabfrage.name_2.text
            self.Spielernamen.append(Name1)
            self.Spielernamen.append(Name2)
            print(Variablen.Spielernamen)
    
    
    class Namensabfrage(Screen):
        name_1 = ObjectProperty()
        name_2 = ObjectProperty()
    
        def save_names(self):
            vars = Variablen()
            vars.get_names(self)
    
    
    class Anzeige(Screen, Variablen):
        Spieler1 = StringProperty("")
        Spieler2 = StringProperty("")
    
        def on_pre_enter(self):
            self.Spieler1 = str(Variablen.Spielernamen[0])
            self.Spieler2 = str(Variablen.Spielernamen[1])
    
    
    class Manager(ScreenManager):
    
        namensabfrage = ObjectProperty(None)
        anzeige = ObjectProperty(None)
    
    
    class ScreensApp(App):
    
        def build(self):
            m = Manager(transition=SlideTransition())
            return m
    
    
    if __name__ == "__main__":
        ScreensApp().run()
    

    screens.kv

    #:kivy 1.10.0
    
    <Namensabfrage>:
    
        name_1: name1
        name_2: name2
    
        Boxlayout:
            orientation: 'vertical'
            padding: 50
            spacing: 50
            Label:
                text: "gebt hier eure Namen ein"
    
            Textinput:
                id: name1
                size_hint: (1, .3)
                text: ""
                multiline: False
    
            Textinput:
                id: name2
                size_hint: (1, .3)
                text: ""
                multiline: False
    
            Button:
                text: "Bestätigen"
                size_hint:(1,.4)
                on_press: root.save_names()
    
            Button:
                size_hint: (1, .5)
                text: "Start"
                on_press: root.manager.current = "Screen2"
    
    
    
    <Anzeige>:
    
        Boxlayout:
            orientation: 'vertical'
            spacing: 50
    
            Label:
                text: root.Spieler1
    
            Label:
                text: root.Spieler2
    
    
    <Manager>:
        id: screen_manager
    
        namensabfrage: Namensabfrage
        anzeige: Anzeige
    
    
        Namensabfrage:
    
            id: Namensabfrage
            name: "Screen1"
            manager: screen_manager
    
        Anzeige:
    
            id: Anzeige
            name: "Screen2"
            manager: screen_manager
    

    Output

    Img01 - App Startup Img02 - Names Entered Img03 - Clicked Confirm Button Img04 - Names Displayed After Clicked Start Button