我正在尝试使用Pthon和kivy进行应用程序。我正在其中的“登录/注册”部分。我正在尝试为每个屏幕(登录和注册)创建一个屏幕,并将它们与ScreenManager连接,但是没有.kv文件。如果不可能的话,我想在.kv文件中写的越少越好
我看过一些教程,说我必须为每个窗口类继承“ Screen”并为ScreenManager创建一个类。然后,在.kv文件中,为每个类设置“名称”变量。之后,我应该在'on_click'函数中使用'root.app.current ='。我试过只用python,然后再用一点KvLang来做,但是没有用。
我尝试使用代码的注释部分,但也没有用
.py文件
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.textinput import TextInput
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
class ScreenManagement(ScreenManager):
def __init__(self, **kwargs):
super(ScreenManagement, self).__init__(**kwargs)
#self.transition = FadeTransition()
#self.add_widget(RegisterWindow(name='register'))
#self.add_widget(LoginWindow(name='login'))
def screen_transition(self, *args):
self.current = 'register'
class RegisterWindow(Screen, FloatLayout):
def __init__(self, **kwargs):
super(RegisterWindow, self).__init__(**kwargs)
self.name = 'register'
self.add_widget(Label(text='Username', size_hint=(.45, .1), pos_hint={'x': .05, 'y': .7}))
self.username = TextInput(multiline=False, size_hint=(.45, .1), pos_hint={'x': .5, 'y': .7})
self.add_widget(self.username)
self.add_widget(Label(text='Password', size_hint=(.45, .1), pos_hint={'x': .05, 'y': .5}))
self.password = TextInput(multiline=False, password=True, size_hint=(.45, .1), pos_hint={'x': .5, 'y': .5})
self.add_widget(self.password)
self.add_widget(Label(text='E-mail', size_hint=(.45, .1), pos_hint={'x': .05, 'y': .3}))
self.email = TextInput(multiline=False, size_hint=(.45, .1), pos_hint={'x': .5, 'y': .3})
self.add_widget(self.email)
self.btn = Button(text='Register', size_hint=(.9, .2), pos_hint={'center_x': .5, 'y': .03})
self.add_widget(self.btn)
self.btn.bind(on_press=self.submit)
def submit(self, instance):
username = self.username.text
password = self.password.text
email = self.email.text
info = {'Username': username,
'Password': password,
'Email': email}
file = open('data.csv', 'a+')
file.write(f'{info["Username"]},{info["Password"]},{info["Email"]}\n')
file.close()
self.username.text = ''
self.password.text = ''
self.email.text = ''
print(info)
class LoginWindow(Screen, FloatLayout):
def __init__(self, **kwargs):
super(LoginWindow, self).__init__(**kwargs)
self.name = 'login'
self.btn2 = Button(text='Go')
self.add_widget(self.btn2)
self.btn2.bind(on_press = ScreenManagement().screen_transition())
class Application(App):
def build(self):
return LoginWindow()
if __name__ == "__main__":
Application().run()
.kv文件
#:import FadeTransition kivy.uix.screenmanager.FadeTransition
ScreenManagement:
transition: FadeTransition()
RegisterWindow:
name: 'register'
LoginWindow:
name: 'login'
它引发异常:kivy.uix.screenmanager.ScreenManagerException:没有名称为“ register”的屏幕。
答案 0 :(得分:1)
您实际上根本不需要任何kv
。这是不含kv
的代码版本:
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.textinput import TextInput
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
class ScreenManagement(ScreenManager):
def __init__(self, **kwargs):
super(ScreenManagement, self).__init__(**kwargs)
class RegisterWindow(Screen):
def __init__(self, **kwargs):
super(RegisterWindow, self).__init__(**kwargs)
self.add_widget(Label(text='Username', size_hint=(.45, .1), pos_hint={'x': .05, 'y': .7}))
self.username = TextInput(multiline=False, size_hint=(.45, .1), pos_hint={'x': .5, 'y': .7})
self.add_widget(self.username)
self.add_widget(Label(text='Password', size_hint=(.45, .1), pos_hint={'x': .05, 'y': .5}))
self.password = TextInput(multiline=False, password=True, size_hint=(.45, .1), pos_hint={'x': .5, 'y': .5})
self.add_widget(self.password)
self.add_widget(Label(text='E-mail', size_hint=(.45, .1), pos_hint={'x': .05, 'y': .3}))
self.email = TextInput(multiline=False, size_hint=(.45, .1), pos_hint={'x': .5, 'y': .3})
self.add_widget(self.email)
self.btn = Button(text='Register', size_hint=(.9, .2), pos_hint={'center_x': .5, 'y': .03})
self.add_widget(self.btn)
self.btn.bind(on_press=self.submit)
def submit(self, instance):
username = self.username.text
password = self.password.text
email = self.email.text
info = {'Username': username,
'Password': password,
'Email': email}
file = open('data.csv', 'a+')
file.write(f'{info["Username"]},{info["Password"]},{info["Email"]}\n')
file.close()
self.username.text = ''
self.password.text = ''
self.email.text = ''
print(info)
class LoginWindow(Screen):
def __init__(self, **kwargs):
super(LoginWindow, self).__init__(**kwargs)
self.btn2 = Button(text='Go')
self.add_widget(self.btn2)
self.btn2.bind(on_press = self.screen_transition)
def screen_transition(self, *args):
self.manager.current = 'register'
class Application(App):
def build(self):
sm = ScreenManagement(transition=FadeTransition())
sm.add_widget(LoginWindow(name='login'))
sm.add_widget(RegisterWindow(name='register'))
return sm
if __name__ == "__main__":
Application().run()
主要更改是ScreenManagement
Screens
方法中App
实例和子build()
的构建。同样,将Go
Button
的绑定更改为同一类中的screen_transition()
方法。并且您的Screen
类不需要扩展FloatLayout
(Screen
是RelativeLayout
)。
答案 1 :(得分:0)
File ".../main.py", line 17, in screen_transition
self.current = 'register'
File "kivy/properties.pyx", line 497, in kivy.properties.Property.__set__
File "kivy/properties.pyx", line 544, in kivy.properties.Property.set
File "kivy/properties.pyx", line 599, in kivy.properties.Property.dispatch
File "kivy/_event.pyx", line 1214, in kivy._event.EventObservers.dispatch
File "kivy/_event.pyx", line 1120, in kivy._event.EventObservers._dispatch
File "/usr/local/lib/python3.7/dist-packages/kivy/uix/screenmanager.py", line 1038, in on_current
screen = self.get_screen(value)
File "/usr/local/lib/python3.7/dist-packages/kivy/uix/screenmanager.py", line 1064, in get_screen
raise ScreenManagerException('No Screen with name "%s".' % name)
kivy.uix.screenmanager.ScreenManagerException: No Screen with name "register".
当Kivy试图切换到屏幕名称,即代码中的'register'
,方法self.current = 'register'
中的screen_transition()
时发生错误。
运行Kivy应用程序时,有两个ScreenManagement
实例。其中一个是通过kv文件ScreenManagement:
创建的,另一个是通过Python代码ScreenManagement().screen_transition()
创建的。在kv文件中创建的实例具有屏幕名称'register'
和'login'
。而用Python代码创建的一个不包含屏幕名称'register'
和'login'
。
需要以下增强功能才能解决该问题。
ScreenManagement:
替换根规则<ScreenManagement>:
#:import FadeTransition kivy.uix.screenmanager.FadeTransition
<ScreenManagement>:
transition: FadeTransition()
RegisterWindow:
name: 'register'
LoginWindow:
name: 'login'
callback
清除小部件并添加小部件self.btn2.bind(on_press=ScreenManagement().screen_transition())
替换为self.btn2.bind(on_press=self.callback)
pass
删除ScreenManagement类中的所有方法class ScreenManagement(ScreenManager):
pass
...
class LoginWindow(Screen, FloatLayout):
def __init__(self, **kwargs):
super(LoginWindow, self).__init__(**kwargs)
...
self.btn2.bind(on_press=self.callback)
def callback(self, instance):
self.clear_widgets()
self.add_widget(ScreenManagement())