Kivy ScreenManager 的当前属性未找到具有所述名称属性的屏幕

问题描述 投票:0回答:1

我希望应用程序在一秒钟后将屏幕从 EntryWindow 屏幕更改为主屏幕。由于我在实际切换屏幕时已经遇到了 ScreenManager 当前属性的问题,因此我什至没有尝试使用 Clock 在 EntryWindow 一秒后触发切换。有人可以帮我解决这个问题吗? 我有 python 版本 3.12、kivy 版本 2.3.0 和 kivymd 版本 1.2.0。 这是我的 .py 文件:

from kivymd.app import MDApp
from kivy.lang.builder import Builder
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.metrics import dp
from kivy.core.window import Window
from kivy.clock import Clock
import random as rd

Window.size = (360,640)

class MainApp(MDApp):
    
    def build(self):
        screen = Builder.load_file("myKv.kv")
        self.theme_cls.primary_palette ="Orange"
        self.theme_cls.primary_hue = "A700"
        self.theme_cls.theme_style="Dark"
        return screen
    
class EntryWindow(Screen):
    def on_enter(self):
        sm.current = "home"       


class Home(Screen):
    pass
class Exercises(Screen):
    pass     

class Gender(Screen):
    
    def on_enter(self):
        self.ids.extractedWord.color = (1,1,1,1)
        f = open(".venv/genderWordDatabase.txt")
        red = f.readlines()
        stripped = [elem.strip() for elem in red]
        separato = [elem.split() for elem in stripped]
        dizWords = {}
        for i in separato:
            dizWords[i[1]] = (i[0],i[2])
        print(dizWords)
        extracted = list(dizWords.keys())[rd.randint(0,len(dizWords)-1)]
        self.ids.extractedWord.font_style = "H6"
        self.ids.extractedWord.text = extracted
    
    def recordUpdate(self,extractedWord,operand):
        f = open(".venv/genderWordDatabase.txt", "r")
        red = f.readlines()
        f.close()
        for i in range(0,len(red)):
            if extractedWord in red[i]:
                red[i] = " ".join(red[i].strip("\n").split()[:-1]) + " " + str(int(red[i].strip("\n").split()[2])+operand)+"\n"
        g = open(".venv/genderWordDatabase.txt", "w")
        g.writelines(red)
        
    def wordExtraction(self):
        self.ids.extractedWord.color = (1,1,1,1)
        f = open(".venv/genderWordDatabase.txt")
        red = f.readlines()
        f.close()
        stripped = [elem.strip() for elem in red]
        separato = [elem.split() for elem in stripped]
        dizWords = {}
        for i in separato:
            dizWords[i[1]] = (i[0],i[2])
        extracted = list(dizWords.keys())[rd.randint(0,len(dizWords)-1)]
        self.ids.extractedWord.font_style = "H6"
        self.ids.extractedWord.text = extracted
    
    def check(self, answer):
        f = open(".venv/genderWordDatabase.txt")
        red = f.readlines()
        f.close()
        stripped = [elem.strip("\n").strip() for elem in red]
        separato = [elem.split() for elem in stripped]
        dizWords = {}
        for i in separato:
            dizWords[i[1]] = (i[0],i[2])
        print(dizWords)
        parola  = self.ids.extractedWord.text
        if dizWords[parola][0] == answer:
            self.ids.extractedWord.color = (0,1,0,1)
            self.ids.extractedWord.font_style = "H6"
            self.ids.extractedWord.text = "Right +1"
            #Chiamo la funzione che aggiorna il record di ciascuna parola
            self.recordUpdate(dizWords[parola][0],1)
            Clock.schedule_once(lambda dt: self.wordExtraction(), 1)
        else:
            self.ids.extractedWord.color = (1,0,0,1)
            self.ids.extractedWord.font_style = "Body1"
            self.ids.extractedWord.text = "Wrong -1, the correct one was: " + dizWords[self.ids.extractedWord.text][0]
            self.recordUpdate(dizWords[parola][0],-1)
            Clock.schedule_once(lambda dt: self.wordExtraction(), 2)

sm =  ScreenManager()
sm.add_widget(EntryWindow(name="starting"))
sm.add_widget(Home(name="home"))
sm.add_widget(Exercises(name="exercises"))
sm.add_widget(Gender(name="gender"))

MainApp().run()

这是我的 .kv 文件:

ScreenManager:
    EntryWindow:
    Home:
    Exercises:
    
<EntryWindow>:
    name: "starting"
    BoxLayout: 
        orientation: "vertical"
        Widget:
        MDLabel:
            text: "German"
            halign: "center"
            markup: True
            color: (1,1,1,1)
            font_style: "H3"
        MDLabel:
            text: "By Staffo"
            markup: True
            color: (1,1,1,1)
            halign: "center"
            font_style: "H6"
        Widget:
        Widget:
<Home>:
    name: "home"
    AnchorLayout:
        anchor_x: "center"
        anchor_y: "center"
        BoxLayout: 
            orientation: "vertical"
            spacing: 30
            Widget:
            MDFillRoundFlatButton:
                text: "exercises"
                pos_hint: {"center_x":0.5,"center_y":0.5}
                on_press:root.manager.current = "exercises"
            MDFillRoundFlatButton:
                text: "customize dictionary"
                pos_hint: {"center_x":0.5,"center_y":0.5}
                #on_press:root.manager.current = "customize"
            MDFillRoundFlatButton:
                text: "Settings"
                pos_hint: {"center_x":0.5,"center_y":0.5}
                #on_press:root.manager.current = "settings"
            MDFillRoundFlatButton:
                text: "Credits"
                pos_hint: {"center_x":0.5,"center_y":0.5}
                #on_press: root.manager.current = "credits"
            Widget:
<Exercises>:
    name: "exercises"
    AnchorLayout:
        anchor_x: "center"
        anchor_y: "center"
        BoxLayout: 
            orientation: "vertical"
            spacing: 30
            Widget:
            MDFillRoundFlatButton:
                text: "[b]M/F/N/P[/b]"
                markup: True
                pos_hint: {"center_x":0.5,"center_y":0.5}
                on_press:root.manager.current = "gender"
                text_color: (1,1,1,1)
                
            MDFillRoundFlatButton:
                text: "[b]Learn New Words[/b]"
                markup: True
                text_color: (1,1,1,1)
                pos_hint: {"center_x":0.5,"center_y":0.5}
                #on_press:root.manager.current = ""
            MDFillRoundFlatButton:
                text: "[b]Phrases[/b]"
                markup: True
                text_color: (1,1,1,1)
                pos_hint: {"center_x":0.5,"center_y":0.5}
                #on_press:root.manager.current = ""
            MDFillRoundFlatButton: 
                text: "[b]Listening[/b]"
                markup: True
                text_color: (1,1,1,1)
                pos_hint: {"center_x":0.5,"center_y":0.5}
                #on_press: root.manager.current = ""
            Widget:
<Gender>:
    name: "gender"
    AnchorLayout:
        anchor_x: "center"
        anchor_y: "center"
        BoxLayout:
            orientation: "vertical"
            Widget:
            Widget:
            Widget:
            MDCard:
                size_hint: .85, 2 
                pos_hint: {"center_x": .5, "center_y": .5}
                MDRelativeLayout:
                    MDLabel:
                        halign: "center"
                        id: extractedWord
                        markup: True
                        text: "extractedWord"
                        font_style: "H6"
                        color: (0,0,0,1)
            BoxLayout:
                spacing: 20
                Widget:
                MDFillRoundFlatButton:  
                    text: "[b]der[/b]"
                    markup: True
                    text_color: (1,1,1,1)
                    on_press: root.check("der")
                MDFillRoundFlatButton:  
                    text: "[b]die[/b]"
                    markup: True
                    text_color: (1,1,1,1)
                    on_press: root.check("die")
                MDFillRoundFlatButton:  
                    text: "[b]das[/b]"
                    markup: True
                    text_color: (1,1,1,1)
                    on_press: root.check("das") 
                Widget:
            Widget:
            Widget:
            Widget:
            Widget:

我收到以下错误:

kivy.uix.screenmanager.ScreenManagerException: No Screen with name "home".
python kivy kivy-language kivymd
1个回答
0
投票

问题出在你的

on_enter()
EntryWindow
方法上。因为您的
kv
创建了一个
EntryWindow
作为第一个
Screen
,并且其
on_enter()
方法在创建其他
Screens
之前就被触发了。一个简单的修复方法是使用
screen
稍微延迟
Clock.schedule_once()
的更改,如下所示:

class EntryWindow(Screen):
    def on_enter(self):
        # delay the Screen switch
        Clock.schedule_once(self.switch_screen)

    def switch_screen(self, _dt):
        self.manager.current = "home"

如您所见,在

switch_screen()
方法中,我将
sm
更改为
self.manager
。您在代码中定义的
sm
未使用,应删除:

# sm = ScreenManager()
# sm.add_widget(EntryWindow(name="starting"))
# sm.add_widget(Home(name="home"))
# sm.add_widget(Exercises(name="exercises"))
# sm.add_widget(Gender(name="gender"))
© www.soinside.com 2019 - 2024. All rights reserved.