如何防止用户在登录 Kivy 之前越过应用程序的登录屏幕
How to keep users from getting past login screen of App before logging in Kivy
它转到的第一个屏幕是登录屏幕,但我可以绕过登录屏幕单击 Actionbar 上的任何按钮。我什至想删除 Actionbar 按钮,然后如果登录成功我可以将它们放回去但是,我无法弄清楚如何从登录屏幕 class 调用 Actionbar 的 id。防止用户绕过应用程序登录屏幕的最佳方法是什么?
Python代码:
from kivy.uix.behaviors import ButtonBehavior
from kivy.uix.image import Image
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import ObjectProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder
from kivy.clock import mainthread
from kivy.uix.button import Button
from kivy.uix.popup import Popup
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.scrollview import ScrollView
Builder.load_file('main.kv')
class Menu(BoxLayout):
manager = ObjectProperty(None)
class ScreenLogIn(Screen):
@mainthread
def verify_credentials(self):
try:
if self.ids.login.text == "email@email.com" and self.ids.passw.text == "password":
self.manager.current = "match"
else:
popup = Popup(title='Try again',
content=Label(text='Wrong Email/Password'),
size_hint=(None, None), size=(400, 400),
auto_dismiss=True)
popup.open()
except Exception as e:
pass
class ScreenNearUsers(Screen):
@mainthread
def on_enter(self):
for i in xrange(101):
button = Button(text="B_" + str(i))
self.ids.grid.add_widget(button)
class ScreenMatch(Screen):
pass
class ScreenChats(Screen):
pass
class ScreenUserProfile(Screen):
pass
class Manager(ScreenManager):
screen_log_in = ObjectProperty(None)
screen_near_user = ObjectProperty(None)
screen_match = ObjectProperty(None)
screen_chats = ObjectProperty(None)
screen_user_profile = ObjectProperty(None)
class MenuApp(App):
def build(self):
return Menu()
if __name__ == '__main__':
MenuApp().run()
主kv:
<Menu>:
manager: screen_manager
orientation: "vertical"
id: action
ActionBar:
size_hint_y: 0.1
background_color: 0, 0, 1000, 10
background_normal: ""
ActionView:
ActionPrevious:
ActionButton:
id: near_users
icon: 'icons/internet.png'
on_press: root.manager.current = 'near_users'
ActionButton:
id: matching_bar
text: "Matching"
on_press: root.manager.current= 'match'
ActionButton:
id: chat
text: "chat"
on_press: root.manager.current = 'chats'
ActionButton:
id: profile
text: "Profile"
on_press: root.manager.current = 'profile'
Manager:
id: screen_manager
<ScreenLogIn>:
orientation: "vertical"
id: login_screen
BoxLayout:
TextInput:
id: login
TextInput:
id: passw
password: True # hide password
Button:
text: "Log In"
on_release: root.verify_credentials()
<ScreenNearUsers>:
ScrollView:
GridLayout:
id: grid
size_hint_y: None
height: self.minimum_height
cols: 2
row_default_height: '20dp'
row_force_default: True
spacing: 0, 0
padding: 0, 0
<ScreenMatch>:
Button:
text:
<ScreenChats>:
Button:
text: "stuff3"
<ScreenUserProfile>:
Button:
text: "stuff4"
<Manager>:
id: screen_manager
screen_log_in: screen_log_in
screen_near_users: screen_near_users
screen_match: screen_match
screen_chats: screen_chats
screen_user_profile: screen_user_profile
ScreenLogIn:
id: screen_log_in
name: 'login'
manager: screen_manager
ScreenNearUsers:
id: screen_near_users
name: 'near_users'
manager: screen_manager
ScreenMatch:
id: screen_match
name: 'match'
manager: screen_manager
ScreenChats:
id: screen_chats
name: 'chats'
manager: screen_manager
ScreenUserProfile:
id: screen_user_profile
name: 'profile'
manger: screen_manager
解决方案
使用 BooleanProperty
和 ActionButton
的 disabled
属性(ActionButtons 变灰)来防止用户访问其他屏幕。
Python代码
- 将 BooleanProperty 添加到导入语句,
from kivy.properties import ObjectProperty, BooleanProperty
- 添加布尔属性,
access_denied = BooleanProperty(True)
在class Menu()
- 在
verify_credentials()
方法中,如果密码匹配,设置access_denied
为False
,否则设置为True
。
片段
from kivy.properties import ObjectProperty, BooleanProperty
...
class Menu(BoxLayout):
access_denied = BooleanProperty(True)
class ScreenLogIn(Screen):
def verify_credentials(self):
try:
if self.ids.login.text == "email@email.com" and self.ids.passw.text == "password":
App.get_running_app().root.access_denied = False
self.manager.current = "match"
else:
App.get_running_app().root.access_denied = True
popup = Popup(title='Try again',
content=Label(text='Wrong Email/Password'),
size_hint=(None, None), size=(400, 400),
auto_dismiss=True)
popup.open()
except Exception as e:
pass
kv 文件
- 检查 BooleanProperty,
access_denied
在每个 ActionButton
片段
ActionButton:
id: near_users
icon: 'icons/internet.png'
disabled: True if root.access_denied else False
on_press: root.manager.current = 'near_users'
ActionButton:
id: matching_bar
text: "Matching"
disabled: True if root.access_denied else False
on_press: root.manager.current= 'match'
ActionButton:
id: chat
text: "chat"
disabled: True if root.access_denied else False
on_press: root.manager.current = 'chats'
ActionButton:
id: profile
text: "Profile"
disabled: True if root.access_denied else False
on_press: root.manager.current = 'profile'
Screen's default property manager
Each screen has by default a property manager that gives you the
instance of the ScreenManager used.
例子
main.py
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import ObjectProperty, BooleanProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder
from kivy.uix.popup import Popup
from kivy.uix.label import Label
from kivy.uix.button import Button
Builder.load_file('main.kv')
class Menu(BoxLayout):
access_denied = BooleanProperty(True)
class ScreenLogIn(Screen):
def verify_credentials(self):
try:
if self.ids.login.text == "email@email.com" and self.ids.passw.text == "password":
App.get_running_app().root.access_denied = False
self.manager.current = "match"
else:
App.get_running_app().root.access_denied = True
popup = Popup(title='Try again',
content=Label(text='Wrong Email/Password'),
size_hint=(None, None), size=(400, 400),
auto_dismiss=True)
popup.open()
except Exception as e:
pass
class ScreenNearUsers(Screen):
def on_enter(self):
for i in range(101):
button = Button(text="B_" + str(i))
self.ids.grid.add_widget(button)
class ScreenMatch(Screen):
pass
class ScreenChats(Screen):
pass
class ScreenUserProfile(Screen):
pass
class Manager(ScreenManager):
screen_log_in = ObjectProperty(None)
screen_near_user = ObjectProperty(None)
screen_match = ObjectProperty(None)
screen_chats = ObjectProperty(None)
screen_user_profile = ObjectProperty(None)
class MenuApp(App):
def build(self):
return Menu()
if __name__ == '__main__':
MenuApp().run()
main.kv
#:kivy 1.11.0
<Menu>:
manager: screen_manager
orientation: "vertical"
id: action
ActionBar:
size_hint_y: 0.1
background_color: 0, 0, 1000, 10
background_normal: ""
ActionView:
ActionPrevious:
ActionButton:
id: near_users
icon: 'icons/internet.png'
disabled: True if root.access_denied else False
on_press: root.manager.current = 'near_users'
ActionButton:
id: matching_bar
text: "Matching"
disabled: True if root.access_denied else False
on_press: root.manager.current= 'match'
ActionButton:
id: chat
text: "chat"
disabled: True if root.access_denied else False
on_press: root.manager.current = 'chats'
ActionButton:
id: profile
text: "Profile"
disabled: True if root.access_denied else False
on_press: root.manager.current = 'profile'
Manager:
id: screen_manager
<ScreenLogIn>:
orientation: "vertical"
id: login_screen
BoxLayout:
TextInput:
id: login
TextInput:
id: passw
password: True # hide password
Button:
text: "Log In"
on_release: root.verify_credentials()
<ScreenNearUsers>:
ScrollView:
GridLayout:
id: grid
size_hint_y: None
height: self.minimum_height
cols: 2
row_default_height: '20dp'
row_force_default: True
spacing: 0, 0
padding: 0, 0
<ScreenMatch>:
Button:
text:
<ScreenChats>:
Button:
text: "stuff3"
<ScreenUserProfile>:
Button:
text: "stuff4"
<Manager>:
screen_log_in: screen_log_in
screen_near_users: screen_near_users
screen_match: screen_match
screen_chats: screen_chats
screen_user_profile: screen_user_profile
ScreenLogIn:
id: screen_log_in
name: 'login'
ScreenNearUsers:
id: screen_near_users
name: 'near_users'
ScreenMatch:
id: screen_match
name: 'match'
ScreenChats:
id: screen_chats
name: 'chats'
ScreenUserProfile:
id: screen_user_profile
name: 'profile'
输出
它转到的第一个屏幕是登录屏幕,但我可以绕过登录屏幕单击 Actionbar 上的任何按钮。我什至想删除 Actionbar 按钮,然后如果登录成功我可以将它们放回去但是,我无法弄清楚如何从登录屏幕 class 调用 Actionbar 的 id。防止用户绕过应用程序登录屏幕的最佳方法是什么?
Python代码:
from kivy.uix.behaviors import ButtonBehavior
from kivy.uix.image import Image
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import ObjectProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder
from kivy.clock import mainthread
from kivy.uix.button import Button
from kivy.uix.popup import Popup
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.scrollview import ScrollView
Builder.load_file('main.kv')
class Menu(BoxLayout):
manager = ObjectProperty(None)
class ScreenLogIn(Screen):
@mainthread
def verify_credentials(self):
try:
if self.ids.login.text == "email@email.com" and self.ids.passw.text == "password":
self.manager.current = "match"
else:
popup = Popup(title='Try again',
content=Label(text='Wrong Email/Password'),
size_hint=(None, None), size=(400, 400),
auto_dismiss=True)
popup.open()
except Exception as e:
pass
class ScreenNearUsers(Screen):
@mainthread
def on_enter(self):
for i in xrange(101):
button = Button(text="B_" + str(i))
self.ids.grid.add_widget(button)
class ScreenMatch(Screen):
pass
class ScreenChats(Screen):
pass
class ScreenUserProfile(Screen):
pass
class Manager(ScreenManager):
screen_log_in = ObjectProperty(None)
screen_near_user = ObjectProperty(None)
screen_match = ObjectProperty(None)
screen_chats = ObjectProperty(None)
screen_user_profile = ObjectProperty(None)
class MenuApp(App):
def build(self):
return Menu()
if __name__ == '__main__':
MenuApp().run()
主kv:
<Menu>:
manager: screen_manager
orientation: "vertical"
id: action
ActionBar:
size_hint_y: 0.1
background_color: 0, 0, 1000, 10
background_normal: ""
ActionView:
ActionPrevious:
ActionButton:
id: near_users
icon: 'icons/internet.png'
on_press: root.manager.current = 'near_users'
ActionButton:
id: matching_bar
text: "Matching"
on_press: root.manager.current= 'match'
ActionButton:
id: chat
text: "chat"
on_press: root.manager.current = 'chats'
ActionButton:
id: profile
text: "Profile"
on_press: root.manager.current = 'profile'
Manager:
id: screen_manager
<ScreenLogIn>:
orientation: "vertical"
id: login_screen
BoxLayout:
TextInput:
id: login
TextInput:
id: passw
password: True # hide password
Button:
text: "Log In"
on_release: root.verify_credentials()
<ScreenNearUsers>:
ScrollView:
GridLayout:
id: grid
size_hint_y: None
height: self.minimum_height
cols: 2
row_default_height: '20dp'
row_force_default: True
spacing: 0, 0
padding: 0, 0
<ScreenMatch>:
Button:
text:
<ScreenChats>:
Button:
text: "stuff3"
<ScreenUserProfile>:
Button:
text: "stuff4"
<Manager>:
id: screen_manager
screen_log_in: screen_log_in
screen_near_users: screen_near_users
screen_match: screen_match
screen_chats: screen_chats
screen_user_profile: screen_user_profile
ScreenLogIn:
id: screen_log_in
name: 'login'
manager: screen_manager
ScreenNearUsers:
id: screen_near_users
name: 'near_users'
manager: screen_manager
ScreenMatch:
id: screen_match
name: 'match'
manager: screen_manager
ScreenChats:
id: screen_chats
name: 'chats'
manager: screen_manager
ScreenUserProfile:
id: screen_user_profile
name: 'profile'
manger: screen_manager
解决方案
使用 BooleanProperty
和 ActionButton
的 disabled
属性(ActionButtons 变灰)来防止用户访问其他屏幕。
Python代码
- 将 BooleanProperty 添加到导入语句,
from kivy.properties import ObjectProperty, BooleanProperty
- 添加布尔属性,
access_denied = BooleanProperty(True)
在class Menu()
- 在
verify_credentials()
方法中,如果密码匹配,设置access_denied
为False
,否则设置为True
。
片段
from kivy.properties import ObjectProperty, BooleanProperty
...
class Menu(BoxLayout):
access_denied = BooleanProperty(True)
class ScreenLogIn(Screen):
def verify_credentials(self):
try:
if self.ids.login.text == "email@email.com" and self.ids.passw.text == "password":
App.get_running_app().root.access_denied = False
self.manager.current = "match"
else:
App.get_running_app().root.access_denied = True
popup = Popup(title='Try again',
content=Label(text='Wrong Email/Password'),
size_hint=(None, None), size=(400, 400),
auto_dismiss=True)
popup.open()
except Exception as e:
pass
kv 文件
- 检查 BooleanProperty,
access_denied
在每个 ActionButton
片段
ActionButton:
id: near_users
icon: 'icons/internet.png'
disabled: True if root.access_denied else False
on_press: root.manager.current = 'near_users'
ActionButton:
id: matching_bar
text: "Matching"
disabled: True if root.access_denied else False
on_press: root.manager.current= 'match'
ActionButton:
id: chat
text: "chat"
disabled: True if root.access_denied else False
on_press: root.manager.current = 'chats'
ActionButton:
id: profile
text: "Profile"
disabled: True if root.access_denied else False
on_press: root.manager.current = 'profile'
Screen's default property manager
Each screen has by default a property manager that gives you the instance of the ScreenManager used.
例子
main.py
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import ObjectProperty, BooleanProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder
from kivy.uix.popup import Popup
from kivy.uix.label import Label
from kivy.uix.button import Button
Builder.load_file('main.kv')
class Menu(BoxLayout):
access_denied = BooleanProperty(True)
class ScreenLogIn(Screen):
def verify_credentials(self):
try:
if self.ids.login.text == "email@email.com" and self.ids.passw.text == "password":
App.get_running_app().root.access_denied = False
self.manager.current = "match"
else:
App.get_running_app().root.access_denied = True
popup = Popup(title='Try again',
content=Label(text='Wrong Email/Password'),
size_hint=(None, None), size=(400, 400),
auto_dismiss=True)
popup.open()
except Exception as e:
pass
class ScreenNearUsers(Screen):
def on_enter(self):
for i in range(101):
button = Button(text="B_" + str(i))
self.ids.grid.add_widget(button)
class ScreenMatch(Screen):
pass
class ScreenChats(Screen):
pass
class ScreenUserProfile(Screen):
pass
class Manager(ScreenManager):
screen_log_in = ObjectProperty(None)
screen_near_user = ObjectProperty(None)
screen_match = ObjectProperty(None)
screen_chats = ObjectProperty(None)
screen_user_profile = ObjectProperty(None)
class MenuApp(App):
def build(self):
return Menu()
if __name__ == '__main__':
MenuApp().run()
main.kv
#:kivy 1.11.0
<Menu>:
manager: screen_manager
orientation: "vertical"
id: action
ActionBar:
size_hint_y: 0.1
background_color: 0, 0, 1000, 10
background_normal: ""
ActionView:
ActionPrevious:
ActionButton:
id: near_users
icon: 'icons/internet.png'
disabled: True if root.access_denied else False
on_press: root.manager.current = 'near_users'
ActionButton:
id: matching_bar
text: "Matching"
disabled: True if root.access_denied else False
on_press: root.manager.current= 'match'
ActionButton:
id: chat
text: "chat"
disabled: True if root.access_denied else False
on_press: root.manager.current = 'chats'
ActionButton:
id: profile
text: "Profile"
disabled: True if root.access_denied else False
on_press: root.manager.current = 'profile'
Manager:
id: screen_manager
<ScreenLogIn>:
orientation: "vertical"
id: login_screen
BoxLayout:
TextInput:
id: login
TextInput:
id: passw
password: True # hide password
Button:
text: "Log In"
on_release: root.verify_credentials()
<ScreenNearUsers>:
ScrollView:
GridLayout:
id: grid
size_hint_y: None
height: self.minimum_height
cols: 2
row_default_height: '20dp'
row_force_default: True
spacing: 0, 0
padding: 0, 0
<ScreenMatch>:
Button:
text:
<ScreenChats>:
Button:
text: "stuff3"
<ScreenUserProfile>:
Button:
text: "stuff4"
<Manager>:
screen_log_in: screen_log_in
screen_near_users: screen_near_users
screen_match: screen_match
screen_chats: screen_chats
screen_user_profile: screen_user_profile
ScreenLogIn:
id: screen_log_in
name: 'login'
ScreenNearUsers:
id: screen_near_users
name: 'near_users'
ScreenMatch:
id: screen_match
name: 'match'
ScreenChats:
id: screen_chats
name: 'chats'
ScreenUserProfile:
id: screen_user_profile
name: 'profile'