我正在尝试制作一个手机应用程序,并希望能够在多个屏幕之间导航。然而,我不知道该如何处理不断返回的语法错误。我是一个新手,看了很多教程的东西来把我的代码放在一起,帮助将非常感激。
下面是主文件
的代码from kivy.uix.screenmanager import ScreenManager, Screen #screen manager is a widget dedicated to managing multiple screens for your application.
from kivy.uix.button import Button #creates the button in kivy
from kivy.uix.floatlayout import FloatLayout #means can place elements based on windows size
from kivy.config import Config
from kivy.properties import ObjectProperty
from kivy.uix.popup import Popup
from kivy.uix.widget import Widget
from kivy.uix.label import Label
Config.set('graphics', 'resizable', True)
kv = Builder.load_file("phoneassistant.kv") #links to kv file where graphics are loaded
sm = WindowManager() #sm will control moving between screens using the ScreenManager class
#creating classes for all screen on app help specify methods for individual screens using argument Screen
class LoginWindow(Screen, FloatLayout):
def mainBtn(self):
self.reset()
sm.current = "main"
def createBtn(self):
self.reset()
sm.current = "create"
class CreateAccountWindow(Screen, FloatLayout):
def loginBtn(self):
self.reset()
sm.current = "login"
class MainWindow(Screen, FloatLayout):
def loginBtn(self):
self.reset()
sm.current = "login"
def settingsBtn(self):
self.reset()
sm.current = "settings"
def storageBtn(self):
self.reset()
sm.current = "storage"
class SettingsWindow(Screen, FloatLayout):
pass
class StorageWindow(Screen, FloatLayout):
pass
class AIWindow(Screen, FloatLayout):
pass
class WindowManager(ScreenManager): #this won't be a sceen, ScreenManager is to manage transitions between all screens
pass
#gives the screens names
screens = [LoginWindow(name = "login"), CreateAccountWindow(name = "create"), MainWindow(name="main"),
SettingsWindow(name = "settings"),StorageWindow(name = "storage"), AIWindow(name = "AI")]
#adds the screens to the manager
for screen in screens:
sm.add_widget(screen)
#sends user to login page whenever program is ran
sm.current = "login"
class PhoneAssistantApp(App): #creates the app class
def build(self):
return sm #returns screens when class is ran
if __name__ == "__main__": #runs the app
PhoneAssistantApp().run()
kv文件上的代码
<ScreenManagement>:
transition: SlideTransition
LoginWindow:
CreateAccountWindow:
MainWindow:
SettingsWindow:
StorageWindow:
AIWindow:
<LoginWindow>:
name: "login"
FloatLayout:
Button:
text: "Don't have an account?"
font_size: 0.2, 0.1
background_color: 0, 0, 1, 1
size_hint: 0.4, 0.3
pos: {"x":0.5, "y":0.25}
on_release:
root.manager.transition.direction = "left"
root.manager.transition.duration = 1
root.createBtn()
Button:
text: "Login here"
font_size: 0.1, 0.2
background_color: 1, 0, 0, 1
size_hint: 0.4, 0.3
pos_hint: {"x":0.5, "y":0.75}
on_release:
root.manager.transition.direction = "right"
root.manager.transition.duration = 1
root.mainBtn()
<CreateAccountWindow>:
name: "create"
FloatLayout:
Button:
text: "Create login"
font_size: 0.25, 0.25
background_color : 1, 1, 0, 1
size_hint: 0.5, 0.5
pos_hint: {"x":0.5, "y":0.1}
on_release:
app.root.current = "login"
root.manager.transition.direction = "right"
root.manager.transition.duration = 1
<MainWindow>:
name: "main"
FloatLayout:
Button:
text: "Return to login page"
font_size: 0.25, 0.25
background_color : 1, 1, 0, 1
size_hint: 0.25, 0.35
pos_hint: {"x":0.5, "y":0.1}
on_release:
app.root.current = "login"
root.manager.transition.direction = "left"
root.manager.transition.duration = 1
Button:
text: "Access Settings"
font_size: 0.5, 0.5
background_color : 1, 0, 1, 1
size_hint: 0.35, 40.5
pos_hint: {"x":0.1, "y":0.9}
on_release:
app.root.current = "settings"
root.manager.transition.direction = "right"
root.manager.transition.duration = 1
Button:
text: "Access Storage"
font_size: 0.75, 0.75
background_color : 1, 1, 1, 0
size_hint: 0.45, 0.25
pos_hint: {"x":0.9, "y":0.5}
on_release:
app.root.current = "storage"
root.manager.transition.direction = "right"
root.manager.transition.duration = 1
<SettingsWindow>:
name: "settings"
FloatLayout:
Button:
text: "Return to Main Menu"
background_color: 0, 1, 1, 1
on_release:
app.root.current = "main"
root.manager.transition.direction = "left"
root.manager.transition.duration = 1
<StorageWindow>:
name: "storage"
FloatLayout:
Button:
text: "Return to Main Menu"
font_size: 0.25, 0.25
background_color : 1, 1, 1, 0
size_hint: 0.5, 0.5
pos_hint: {"x":0.1, "y":0.1}
background_color: 1, 0, 0, 1
on_release:
app.root.current = "main"
root.manager.transition.direction = "left"
root.manager.transition.duration = 1
Button:
text: "Access AI"
font_size: 0.25, 0.25
background_color : 1, 1, 1, 0
size_hint: 0.5, 0.5
pos_hint: {"x":0.9, "y":0.9}
background_color: 1, 1, 0, 0
on_release:
app.root.current = "ai"
root.manager.transition.direction = "right"
root.manager.transition.duration = 1
<AIWindow>
name: "ai"
FloatLayout:
Button:
text: "Return to Storage"
background_color: 0, 1, 1, 0
on_release:
app.root.current = "storage"
root.manager.transition.direction = "left"
root.manager.transition.duration = 1
和错误
Traceback (most recent call last):
line 15, in <module>
kv = Builder.load_file("phoneassistant.kv") #links to kv file where graphics are loaded
line 305, in load_file
return self.load_string(data, **kwargs)
line 372, in load_string
parser = Parser(content=string, filename=fn)
line 483, in __init__
self.parse(content)
line 593, in parse
objects, remaining_lines = self.parse_level(0, lines)
line 756, in parse_level
if current_property[:3] == 'on_':
TypeError: 'NoneType' object is not subscriptable
我试过改变我使用的模块,比如改变到BoxLayout,看看是否会起作用并将on_press更改为on_release,有时尝试在kv文件中同时使用另外,在kv文件中增加了过渡到屏幕管理类还在主程序
的login、create和main类中创建了def语句。这些都主要是因为我认为主要问题是on_release按钮,但它也可能是我的代码结构。
我不知道你的代码会在哪里产生这个错误,但可能你的kivy文件在某个地方有缩进问题。有些东西可能被过度缩进或丢失,以至于没有对象存在。下面的代码是可运行的,但我不认为它有你想要的布局抛光。我冒昧地为您的LoginWindow添加了一些我认为您可能想要使用的示例方法。
我不确定reset()是什么意思,因为你没有匹配的代码,所以我把它改成了打印到控制台的东西。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from kivy.lang import Builder
# screen manager is a widget dedicated to managing multiple screens for your application.
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.button import Button # creates the button in kivy
from kivy.uix.floatlayout import FloatLayout # means can place elements based on windows size
from kivy.config import Config
from kivy.properties import StringProperty, BooleanProperty, ListProperty, NumericProperty
from kivy.uix.popup import Popup
from kivy.uix.label import Label
from kivy.app import App
kv = Builder.load_string('''
# <ScreenManagement>:
# transition: SlideTransition
# LoginWindow:
# CreateAccountWindow:
# MainWindow:
# SettingsWindow:
# StorageWindow:
# AIWindow:
<LoginWindow>:
name: "login"
FloatLayout:
Button:
text: "Don't have an account?"
# font_size: 0.2, 0.1
background_color: 0, 0, 1, 1
size_hint: 0.4, 0.3
# pos: {"x":0.5, "y":0.25}
on_release:
root.manager.transition.direction = "left"
root.manager.transition.duration = 1
root.createBtn()
Button:
text: "Login here"
# font_size: 0.1, 0.2
background_color: 1, 0, 0, 1
size_hint: 0.4, 0.3
pos_hint: {"x":0.5, "y":0.75}
on_release:
root.manager.transition.direction = "right"
root.manager.transition.duration = 1
root.mainBtn()
<CreateAccountWindow>:
name: "create"
FloatLayout:
Button:
text: "Create login"
# font_size: 0.25, 0.25
background_color : 1, 1, 0, 1
size_hint: 0.5, 0.5
pos_hint: {"x":0.5, "y":0.1}
on_release:
app.root.current = "login"
root.manager.transition.direction = "right"
root.manager.transition.duration = 1
<MainWindow>:
name: "main"
FloatLayout:
Button:
text: "Return to login page"
# font_size: 0.25, 0.25
background_color : 1, 1, 0, 1
size_hint: 0.25, 0.35
pos_hint: {"x":0.5, "y":0.1}
on_release:
app.root.current = "login"
root.manager.transition.direction = "left"
root.manager.transition.duration = 1
Button:
text: "Access Settings"
# font_size: 0.5, 0.5
background_color : 1, 0, 1, 1
size_hint: 0.35, 40.5
pos_hint: {"x":0.1, "y":0.9}
on_release:
app.root.current = "settings"
root.manager.transition.direction = "right"
root.manager.transition.duration = 1
Button:
text: "Access Storage"
# font_size: 0.75, 0.75
background_color : 1, 1, 1, 0
size_hint: 0.45, 0.25
pos_hint: {"x":0.9, "y":0.5}
on_release:
app.root.current = "storage"
root.manager.transition.direction = "right"
root.manager.transition.duration = 1
<SettingsWindow>:
name: "settings"
FloatLayout:
Button:
text: "Return to Main Menu"
background_color: 0, 1, 1, 1
on_release:
app.root.current = "main"
root.manager.transition.direction = "left"
root.manager.transition.duration = 1
<StorageWindow>:
name: "storage"
FloatLayout:
Button:
text: "Return to Main Menu"
# font_size: 0.25, 0.25
background_color : 1, 1, 1, 0
size_hint: 0.5, 0.5
pos_hint: {"x":0.1, "y":0.1}
background_color: 1, 0, 0, 1
on_release:
app.root.current = "main"
root.manager.transition.direction = "left"
root.manager.transition.duration = 1
Button:
text: "Access AI"
# font_size: 0.25, 0.25
background_color : 1, 1, 1, 0
size_hint: 0.5, 0.5
pos_hint: {"x":0.9, "y":0.9}
background_color: 1, 1, 0, 0
on_release:
app.root.current = "ai"
root.manager.transition.direction = "right"
root.manager.transition.duration = 1
<AIWindow>
name: "ai"
FloatLayout:
Button:
text: "Return to Storage"
background_color: 0, 1, 1, 0
on_release:
app.root.current = "storage"
root.manager.transition.direction = "left"
root.manager.transition.duration = 1
''')
Config.set('graphics', 'resizable', True)
# creating classes for all screen on app help specify methods for individual screens using argument Screen
class LoginWindow(Screen, FloatLayout):
def on_pre_enter(self, *args):
print(" on pre-enter")
def on_enter(self, *args):
print("on enter")
def on_leave(self, *args):
print("login leave")
def on_pre_leave(self, *args):
print("pre-leave")
def reset(self):
print(f"reset {self}")
def mainBtn(self):
self.reset()
App.get_running_app().root.current = "main"
def createBtn(self):
self.reset()
App.get_running_app().root.current = "create"
class CreateAccountWindow(Screen, FloatLayout):
def reset(self):
print(f"{self}")
def loginBtn(self):
self.reset()
App.get_running_app().root.current = "login"
class MainWindow(Screen, FloatLayout):
def reset(self):
print(f"{self}")
def loginBtn(self):
self.reset()
App.get_running_app().root.current = "login"
def settingsBtn(self):
self.reset()
App.get_running_app().root.current = "settings"
def storageBtn(self):
self.reset()
App.get_running_app().root.current = "storage"
class SettingsWindow(Screen, FloatLayout):
pass
class StorageWindow(Screen, FloatLayout):
pass
class AIWindow(Screen, FloatLayout):
pass
class PhoneAssistantApp(App): # creates the app class
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.sm = ScreenManager() # sm will control moving between screens using the ScreenManager class
# gives the screens names
self.screens = (LoginWindow(name="login"), CreateAccountWindow(name="create"), MainWindow(name="main"),
SettingsWindow(name="settings"), StorageWindow(name="storage"), AIWindow(name="AI"))
def build(self) -> ScreenManager:
# adds the screens to the manager
for screen in self.screens:
self.sm.add_widget(screen)
# user to login page whenever program is ran
self.sm.current = "login"
return self.sm # returns screens when class is ran
if __name__ == "__main__":
PhoneAssistantApp().run()