'I can't switch screen in kivy

I followed a tutorial on youtube so I could learn how to use kivy, but when I try to switch screen it doesn't work, I write my code the exact same way the guy does it, but for some reason nothing happens when I click the button "Se dine produkter".

I have written where I need help in the .kv file, I added the rest of the code only in case if you need to know why I have done certain things. In line 10 and 25 I have written what I want to happen, I have tried so many different things and different ways to approach what I want, but I haven't succeed with any of them.

main.py:

import kivy
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import ObjectProperty
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.popup import Popup
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen

Builder.load_file("struktur.kv")

class HovedVindu(Screen and Widget):
    def nyttProdukt(self):
        show_popup()
    
    def dineProdukter(self):
        print("dine produkter")
        ScreenManager.current = "dineprodukter"

    def leggTilNyttProdukt(self, navn, dato):
        self.navn = navn
        self.dato = dato
        print(self.navn, self.dato)


class DineProdukter(Screen):
    pass

class WindowManager(ScreenManager):
    pass

class P(FloatLayout):
    pass

class MainApp(App):
    def build(self):
        return HovedVindu()

def show_popup():
    show = P()
    popupWindow = Popup(title="Legg til ett nytt produkt", content=show, size_hint=(None,None),size=(400,400), title_align="center")
    popupWindow.open()

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

struktur.kv:

#:kivy 2.1.0
<WindowManager>:
    HovedVindu:
    DineProdukter:

<DineProdukter>:
    name: "dineprodukter"
    Button:
        text: "Go to main"
        on_release: switch to (hoved)

<HovedVindu>:
    name: "hoved"
    FloatLayout:
        Button:
            text: "Nytt produkt"
            size_hint: 2, 1
            pos_hint: {"x": 3, "top": 5} 
            on_release: root.nyttProdukt()

        Button:
            text: "Se dine produkter"
            size_hint: 2, 1
            pos_hint: {"x": 3, "top": 3}
            on_release: switch to (dineprodukter)

<P>:
    TextInput:
        hint_text: "Navnet på produktet"
        size_hint: .6, .15
        pos_hint: {"x": .2, "top": .9}

    TextInput:
        hint_text: "Siste forbruksdag"
        size_hint: .6, .15
        pos_hint: {"x": .2, "top": .7}
        
    Button:
        text: "Legg til produkt"
        size_hint: 0.8, 0.2
        pos_hint: {"x":0.1, "y":0.1}


Solution 1:[1]

It happens because you are actually not using Screen Manager. Please follow official kivy documentation on how to use ScreenManager.

https://kivy.org/doc/stable/api-kivy.uix.screenmanager.html

Example code of build function using ScreenManager:

def build(self) -> ScreenManager:
    self.sm = ScreenManager()
    self.sm.add_widget(SplashScreen(name='splash_screen'))
    self.sm.add_widget(DownloadScreen(name='download_screen'))
    self.sm.add_widget(InfoScreen(name='info_screen'))
    self.sm.add_widget(FileManager(name='file_manager'))
    return self.sm

Example usage in .kv file:

MDFillRoundFlatIconButton:
    text: 'Download'
    icon: 'download'
    pos_hint: {'x': 0.77, 'y': 0.01}
    md_bg_color: 64/255, 120/255, 192/255, 1
    on_press:
        root.manager.transition.direction = 'right'
        root.manager.current = 'download_screen'

There is some other ways to do it, but I don't think your code is exactly the same as the code of the guy from YouTube. Stick to kivy documentation, it is actually good and you will learn 'kivy ways' of doing things.

Using switch_to(screen_name) not switch to(screen_name) won't work either if you won't use instance of your Screen Manager. Without that is just non existing function.

Here please you have your code fixed up a bit:

import kivy
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import ObjectProperty
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.popup import Popup
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen

Builder.load_file("struktur.kv")

class HovedVindu(Screen):
    def nyttProdukt(self):
        show_popup()
    
    def dineProdukter(self):
        print("dine produkter")
        ScreenManager.current = "dineprodukter"

    def leggTilNyttProdukt(self, navn, dato):
        self.navn = navn
        self.dato = dato
        print(self.navn, self.dato)


class DineProdukter(Screen):
    pass

 
class P(FloatLayout):
    pass

class MainApp(App):
    def build(self):
        sm = ScreenManager()
        sm.add_widget(HovedVindu(name="hoved"))
        sm.add_widget(DineProdukter(name="dineprodukter"))
        return sm

def show_popup():
    show = P()
    popupWindow = Popup(title="Legg til ett nytt produkt", content=show, size_hint=(None,None),size=(400,400), title_align="center")
    popupWindow.open()

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

And kivy file:

#:kivy 2.1.0


<DineProdukter>:
    FloatLayout:
        Button:
            text: "Go to main"
            pos_hint: {"center_x": .5, "center_y": .5}
            size_hint: .2, .2
            on_release: root.manager.current = "hoved"

<HovedVindu>:
    FloatLayout:
        Button:
            text: "Nytt produkt"
            size_hint: .3, .1
            pos_hint: {"x": .7, "y": .5} 
            on_release: root.nyttProdukt()

        Button:
            text: "Se dine produkter"
            size_hint: .3, .1
            pos_hint: {"x": .3, "y": .5} 
            on_release: root.manager.current = "dineprodukter"

<P>:
    TextInput:
        hint_text: "Navnet på produktet"
        size_hint: .6, .15
        pos_hint: {"x": .2, "top": .9}

    TextInput:
        hint_text: "Siste forbruksdag"
        size_hint: .6, .15
        pos_hint: {"x": .2, "top": .7}
        
    Button:
        text: "Legg til produkt"
        size_hint: 0.8, 0.2
        pos_hint: {"x":0.1, "y":0.1}

Haven't done everything but it displays screens and buttons do work. I have kicked out your class of ScreenManager and actually created an instance of it in the root of your app. That way you can call it from any screen, as they are added to the Manager. Like you need to give screens to the Manager before it can manage it. That way always works fine and you won't experience any problems even if your app will contain 20 or more different classes with screens.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1