在 .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
将被提高。
2。 Screen
小部件有一个 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
中,也许这是不同的。
我正在尝试制作这个具有多个屏幕的应用程序。我在我的 .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
将被提高。
2。 Screen
小部件有一个 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
中,也许这是不同的。