无法在 Kivy 中引用小部件 ID
Can't reference widget id in Kivy
对 Kivy 很陌生,正在尝试动态添加小部件,但是尽管我已经遵循了所有示例,但我还是无法正常工作。
我的 .kv 文件是...
ScreenManager:
MainScreen:
LoginScreen:
<MainScreen>:
name: 'MainScreen'
id: ms
BoxLayout:
id: rc_display
orientation: "vertical"
padding: 10
spacing: 10
Label:
id: ms_label1
text: 'Oh Hell Yeah'
<LoginScreen>:
name: 'LoginScreen'
id: ls
Button:
on_release: app.root.current
text: 'Click to Login'
font_size: 20
我的 python 代码是...
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
import requests
class MainScreen(Screen):
def on_pre_enter(self, *args):
show_view = self.ids.rc_display # error here
show_view.clear_widgets()
buttons = BoxLayout(orientation = 'vertical')
pr = requests.get('http://127.0.0.1:5000/stageplanning/api/v1.0/shows')
for show in pr.json():
buttons.add_widget(Button(text = show['show_title']))
show_view.add_widgets(buttons)
class LoginScreen(Screen):
pass
class ScreenManagement(ScreenManager):
pass
class StagePlanningApp(App):
def build(self):
sm = Builder.load_file('StagePlanning.kv')
# sm.add_widget(MainScreen())
# sm.add_widget(LoginScreen())
return sm
sp_app = StagePlanningApp()
sp_app.run()
当我 运行 以上时,我得到以下错误...
File "*pathtoFile*/StagePlanning.py", line 12, in on_pre_enter
show_view = self.ids.rc_display
File "kivy\properties.pyx", line 839, in kivy.properties.ObservableDict.__getattr__ (kivy\properties.c:12654)
AttributeError: 'super' object has no attribute '__getattr__'
如果我将小部件直接添加到它们显示的 Screen 对象,但会彼此叠加。只有当我尝试引用 id 时才会出现错误。
我什至向控制台打印了 ID 列表,它们如预期的那样存在。
问题是因为 on_pre_enter
事件在添加 BoxLayout
之前完成所以它不存在,一个可能的解决方案是使用 Clock
:
class MainScreen(Screen):
def __init__(self, *args, **kwargs):
Screen.__init__(self, *args, **kwargs)
Clock.schedule_once(self.finished_init)
def finished_init(self, *args):
show_view = self.ids.rc_display # error here
show_view.clear_widgets()
buttons = BoxLayout(orientation = 'vertical')
pr = requests.get('http://127.0.0.1:5000/stageplanning/api/v1.0/shows')
for show in pr.json():
buttons.add_widget(Button(text = show['show_title']))
show_view.add_widget(buttons)
另一种选择是在 BoxLayout 构造函数中定义它:
*.py
class MainBoxLayout(BoxLayout):
def __init__(self, *args, **kwargs):
BoxLayout.__init__(self, *args, **kwargs)
self.clear_widgets()
buttons = BoxLayout(orientation = 'vertical')
pr = requests.get('http://127.0.0.1:5000/stageplanning/api/v1.0/shows')
for show in pr.json():
buttons.add_widget(Button(text = show['show_title']))
self.add_widget(buttons)
*.kv
ScreenManager:
MainScreen:
LoginScreen:
<MainScreen>:
name: 'MainScreen'
id: ms
MainBoxLayout:
id: rc_display
orientation: "vertical"
padding: 10
spacing: 10
<LoginScreen>:
name: 'LoginScreen'
id: ls
Button:
on_release: app.root.current
text: 'Click to Login'
font_size: 20
对 Kivy 很陌生,正在尝试动态添加小部件,但是尽管我已经遵循了所有示例,但我还是无法正常工作。
我的 .kv 文件是...
ScreenManager:
MainScreen:
LoginScreen:
<MainScreen>:
name: 'MainScreen'
id: ms
BoxLayout:
id: rc_display
orientation: "vertical"
padding: 10
spacing: 10
Label:
id: ms_label1
text: 'Oh Hell Yeah'
<LoginScreen>:
name: 'LoginScreen'
id: ls
Button:
on_release: app.root.current
text: 'Click to Login'
font_size: 20
我的 python 代码是...
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
import requests
class MainScreen(Screen):
def on_pre_enter(self, *args):
show_view = self.ids.rc_display # error here
show_view.clear_widgets()
buttons = BoxLayout(orientation = 'vertical')
pr = requests.get('http://127.0.0.1:5000/stageplanning/api/v1.0/shows')
for show in pr.json():
buttons.add_widget(Button(text = show['show_title']))
show_view.add_widgets(buttons)
class LoginScreen(Screen):
pass
class ScreenManagement(ScreenManager):
pass
class StagePlanningApp(App):
def build(self):
sm = Builder.load_file('StagePlanning.kv')
# sm.add_widget(MainScreen())
# sm.add_widget(LoginScreen())
return sm
sp_app = StagePlanningApp()
sp_app.run()
当我 运行 以上时,我得到以下错误...
File "*pathtoFile*/StagePlanning.py", line 12, in on_pre_enter
show_view = self.ids.rc_display
File "kivy\properties.pyx", line 839, in kivy.properties.ObservableDict.__getattr__ (kivy\properties.c:12654)
AttributeError: 'super' object has no attribute '__getattr__'
如果我将小部件直接添加到它们显示的 Screen 对象,但会彼此叠加。只有当我尝试引用 id 时才会出现错误。
我什至向控制台打印了 ID 列表,它们如预期的那样存在。
问题是因为 on_pre_enter
事件在添加 BoxLayout
之前完成所以它不存在,一个可能的解决方案是使用 Clock
:
class MainScreen(Screen):
def __init__(self, *args, **kwargs):
Screen.__init__(self, *args, **kwargs)
Clock.schedule_once(self.finished_init)
def finished_init(self, *args):
show_view = self.ids.rc_display # error here
show_view.clear_widgets()
buttons = BoxLayout(orientation = 'vertical')
pr = requests.get('http://127.0.0.1:5000/stageplanning/api/v1.0/shows')
for show in pr.json():
buttons.add_widget(Button(text = show['show_title']))
show_view.add_widget(buttons)
另一种选择是在 BoxLayout 构造函数中定义它:
*.py
class MainBoxLayout(BoxLayout):
def __init__(self, *args, **kwargs):
BoxLayout.__init__(self, *args, **kwargs)
self.clear_widgets()
buttons = BoxLayout(orientation = 'vertical')
pr = requests.get('http://127.0.0.1:5000/stageplanning/api/v1.0/shows')
for show in pr.json():
buttons.add_widget(Button(text = show['show_title']))
self.add_widget(buttons)
*.kv
ScreenManager:
MainScreen:
LoginScreen:
<MainScreen>:
name: 'MainScreen'
id: ms
MainBoxLayout:
id: rc_display
orientation: "vertical"
padding: 10
spacing: 10
<LoginScreen>:
name: 'LoginScreen'
id: ls
Button:
on_release: app.root.current
text: 'Click to Login'
font_size: 20