在 .kv 中使用 Screenmanager 时出现未知 class <classname> 错误,但 screenmanager 在 .py 中工作正常

Unknown class <classname> error when using Screenmanager in .kv but screenmanager works fine in .py

我正在尝试制作这个具有多个屏幕的应用程序。我在我的 .py 文件中创建了屏幕管理器,一切都按预期工作,但我认为我需要在我的 .kv 文件中编写屏幕管理器。但这就是行不通。我收到此错误 kivy.factory.FactoryException: Unknown class <Home> 我的家 class 在我的 .kv 文件中正确定义,所以我不知道为什么会发生这种情况。我猜也许我需要以某种方式定义当前屏幕,但不知道如何定义。我认为只有 screenmanager 和 home class 值得一看。感谢任何帮助或指导。

这是我的 kv 文件

#:import dp kivy.metrics.dp
#:import ScreenManager kivy.uix.screenmanager.ScreenManager
#:import Screen kivy.uix.screenmanager.ScreenManager
#:set navbar_button_color (59/255, 68/255, 75/255, 1)

ScreenManager:
    id: screen_manager
    Home:
        id: home
        name: "home_screen"
        manager: "screen_manager"
    Daily:
        id: daily
        name: "daily_screen"
        manager: "screen_manager"
    Weekly:
        id: weekly
        name: "weekly_screen"
        manager: "screen_manager"
    Monthly:
        id: monthly
        name: "monthly_screen"
        manager: "screen_manager"
    Yearly:
        id: yearly
        name: "yearly_screen"
        manager: "screen_manager"                

<MyLayout>:
    my_grid: my_grid
    expense_button: expense_button
    orientation: "vertical"
    BoxLayout:
        size_hint: 1,0.1
        Button:
            text: "Back"
            size_hint: 0.1,1
            # on_press:
            #     app.root.manager.current = "home_screen"
            #     app.root.manager.transition.direction = "right" 
        Button:
            text: "Home"
            size_hint: 0.1,1
        Button:
            text: "Daily"
            size_hint: 0.1,1
        Button:
            text: "Weekly"
            size_hint: 0.1,1
        Button:
            text: "Monthly" 
            size_hint: 0.1,1  
        Button:
            text: "Load" 
            size_hint: 0.1,1 
            on_press: my_grid.load()               
        Button:
            text: "Save" 
            size_hint: 0.1,1 
            on_press: my_grid.save() 
        Label:
            text: dt.today().strftime("%d %B %Y")
            size_hint: 0.3,1
            canvas.before:
                Color:
                    rgb: 59/255, 78/255, 85/255,1
                Rectangle:
                    size: self.size
                    pos: self.pos                  
    BoxLayout:
        size_hint: 1,0.15
        Button:
            text: "EXPENSES"            
        Button:
            text: "REVENUE"    
    HeaderBox:
    MyScroll:    
        MyGrid:
            id: my_grid
            size_hint: 1, None
            height: self.minimum_height 
    BoxLayout:
        orientation:"horizontal"
        size_hint: 1,0.2       
        BoxLayout:
            orientation: "vertical"
            Button:
                id: expense_button
                text: "Expense Total:"
                font_size: dp(20)
                on_press:
                    self.text = "Expense Total: " + str(my_grid.expense_total)
                    revenue_button.text = "Revenue Total: " + str(my_grid.revenue_total)
                    profit_button.text = "Profit: " + str(my_grid.profit)
            Button:
                id: revenue_button
                text: "Revenue Total: " 
                font_size: dp(20)
                on_press:
                    expense_button.text = "Expense Total: " + str(my_grid.expense_total)
                    self.text = "Revenue Total: " + str(my_grid.revenue_total)
                    profit_button.text = "Profit: " + str(my_grid.profit)
        Button:
            id: profit_button
            text: "Profit:"
            font_size: dp(40)       
            on_press:
                expense_button.text = "Expense Total: " + str(my_grid.expense_total)
                revenue_button.text = "Revenue Total: " + str(my_grid.revenue_total)
                self.text = "Profit: " + str(my_grid.profit)            

<Home>:
    BoxLayout:
        orientation: "horizontal"
        BoxLayout:
            orientation: "vertical"
            size_hint: 0.65, 1
            spacing: 5
            padding: 5
            Button:
                text: "Daily"
                font_size: 40
                size_hint: 1, 0.75
                background_color: 59/255, 68/255, 75/255, 1
                on_press:
                    root.manager.current = "daily_screen"
                    root.manager.transition.direction = "left" 
                    root.manager.transition.duration = 0.8
            Button:
                text: "Yearly"
                font_size: 40  
                size_hint: 1, 0.25
                background_color: 101/255, 115/255, 131/255, 1
        BoxLayout:
            orientation: "vertical"
            size_hint: 0.35,1
            spacing: 5
            padding: [0,5,5,5]
            Button:
                text: "Weekly"
                font_size: 40
                size_hint: 1, 0.50
                background_color: 84/255, 98/255, 111/255, 1
            Button:
                text: "Monthly"
                font_size: 40  
                size_hint: 1, 0.50
                background_color: 152/255, 175/255, 199/255, 1

<Daily>:
    MyLayout:    
<Weekly>:
    Label:
        text:"Weekly"
<Monthly>:
    Label: 
        text:"Monthly"
<Yearly>:        ```


#for @ApuCoder #我看到一个类似的问题并更改了我的应用程序class的return语句。现在它抛出一个不同的错误。我也不认为 class 是问题的根源,因为我删除了那个 class 然后它说下一个 class 是未定义的。所以这是另一回事。无论如何,我现在有一个新的错误要处理。

root.manager.current = "daily_screen" AttributeError: 'str' 对象没有属性 'current'```

class Home(Screen):
    pass

class MyApp(App):
    def build(self):
        return Builder.load_file("sample1.kv")

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

您的代码存在一些问题,让我们尝试一一解决。

1。在 kvlang 中,您要么从 .py 设计一个预定义的 class,要么在其自身中定义一个 class。因此,您要么在 .py

class MyButton(Button):
    # Some prop. and/or methods if needed.
    # Otherwise,
    pass

然后在 kvlang 中为此 class,

<MyButton>:
    # Whatever you want...

或者等效地,您可以将 kvlang 中的 class (dynamic class ) 定义和设计为,

<MyButton@Button>:
    # Here is your design rule.

现在,如果您尝试在 [=16] 内设计它,则无需从 Widget(或准确地说是 EventDispatcher)继承新的 class(不是默认的) =] 一个 FactoryException 将被提高。

2Screen 小部件有一个 read-only 属性 manager 本质上是一个 ScreenManager 小部件。因此当你做这样的事情时,

ScreenManager:
    id: screen_manager
    Home:
        id: home
        name: "home_screen"
        manager: "screen_manager"

即给它分配一个字符串,你只需用一个字符串覆盖它的默认管理器,这就是为什么你在尝试这样的事情时收到错误消息 AttributeError: 'str' object has no attribute 'current'

root.manager.current = "daily_screen"

从那个屏幕。

你需要做的是,

ScreenManager:
    id: screen_manager # Pass this id to the screen.
    Home:
        id: home
        name: "home_screen"
        manager: screen_manager # Although its not necessary to pass it over.

另外我认为你不能在 python 中分配它,因为它是 read-only 属性。在kvlang中,也许这是不同的。