我无法在 kivy 中切换屏幕

I can't switch screen in kivy

我按照 youtube 上的教程学习了如何使用 kivy,但是当我尝试切换屏幕时它不起作用,我编写代码的方式与那个人完全一样,但出于某种原因当我点击“Se dine produkter”按钮时没有任何反应。

我已经在 .kv 文件中写下了我需要帮助的地方,我添加了其余代码只是为了以防万一您需要知道为什么我做了某些事情。在第 10 行和第 25 行,我写了我想要发生的事情,我尝试了很多不同的事情和不同的方法来实现我想要的,但我没有成功。

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}

发生这种情况是因为您实际上没有使用屏幕管理器。 请按照 kivy 官方文档了解如何使用 ScreenManager。

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

使用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

.kv 文件中的示例用法:

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'

还有一些其他方法可以做到这一点,但我认为您的代码与 YouTube 上那个人的代码并不完全相同。坚持 kivy 文档,它实际上很好,你将学习 'kivy ways' 做事。

如果您不使用屏幕管理器实例,则使用 switch_to(screen_name) 而不是 switch to(screen_name) 也不会起作用。没有它就是不存在的功能。

这里请稍微修改一下代码:

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()

和kivy文件:

#: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}

尚未完成所有操作,但显示屏幕和按钮可以正常工作。 我已经踢出了你的 class 的 ScreenManager 并实际上在你的应用程序的根目录中创建了它的一个实例。这样你就可以从任何屏幕调用它,因为它们被添加到管理器中。就像您需要先将屏幕交给 Manager 才能进行管理一样。这种方式总是可以正常工作,即使您的应用包含 20 种或更多不同的 classes 屏幕,您也不会遇到任何问题。