python - Kivy - 在其他屏幕中创建的访问实例
问题描述
我在我的第一个 Screen 中创建了一个类(Player 类)的一些实例,并希望在另一个 Screen 中访问这些实例(及其数据)。这个想法是这样的:
Player class
:这个类的实例包含玩家的名字和他们的分数。(完毕)WelcomeWindow(Screen) class
:通过 TextInput 提取玩家名称 + 创建 Player 类的实例并分配名称。(完毕)ThirdRound(Screen) class
:访问播放器实例的名称和点,在标签上显示名称并在按下 +/- 按钮时更改播放器点。(问题)
我在下面的代码中标记了我尝试访问实例的位置,但出现了错误:
AttributeError: 'NoneType' object has no attribute 'get_screen'
我的问题是:如何访问玩家点ThirdRound(Screen) class
以便在标签上显示他们的点并在按下 +/- 按钮时更改点?
(我搜索了类似的案例,但无法将它们应用于我的案例。)
.py 文件:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.textinput import TextInput
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.properties import ObjectProperty, NumericProperty
class Player:
def __init__(self, name):
self.name = name
self.points = 0
def reset_points(self):
self.points = 0
def add_point(self, *args):
self.points += 1
def subtract_point(self, *args):
self.points -= 1
class WelcomeWindow(Screen):
# Introduce names of the 4 players
def __init__(self, **kwargs):
super(WelcomeWindow, self).__init__(**kwargs)
self.name = "welcomewindow"
# Create global layout of HOME screen
global_layout = GridLayout(rows=3)
self.add_widget(global_layout)
# Some code with labels and buttons
# Create button to go to next screen
go_further_button = Button(text="Go to first round")
go_further_button.bind(on_release=self.go_further)
global_layout.add_widget(go_further_button)
def go_further(self, *args):
#Give names to players
self.player1 = Player("name1") # <--- 4 player instances are created here
self.player2 = Player("name2")
self.player3 = Player("name3")
self.player4 = Player("name4")
self.manager.current = "thirdround"
self.manager.transition.direction = "left"
class ThirdRound(Screen):
def __init__(self, **kwargs):
super(ThirdRound, self).__init__(**kwargs)
self.name = "thirdround"
welcome_window = self.manager.get_screen('welcomewindow') # <--- Trying to access player instances here but failed
self.player1_points = welcome_window.player1.points
def change_label(self, add_sub, *args): # <--- method which will change the points of the player instance
label = self.ids['testlabel']
if add_sub == 'add':
label.text = 'should add one point'
elif add_sub == 'sub':
label.text = 'should subtract one point'
kv = Builder.load_file("Kingen.kv")
WindowManager = ScreenManager()
WindowManager.add_widget(WelcomeWindow())
WindowManager.add_widget(ThirdRound())
class KingenApp(App):
def build(self):
return WindowManager
if __name__ == "__main__":
KingenApp().run()
.kv 文件:
<ThirdRound>:
GridLayout:
rows: 3
Label:
id: testlabel
text: 'shows number of points here'
Button:
text: "+"
on_release: root.change_label('add')
Button:
text: "-"
on_release: root.change_label('sub')
解决方案
The __init__()
method of ThirdRound
is called at the line:
WindowManager.add_widget(ThirdRound())
Specifically, the ThirdRound()
is executed before the WindowManager.add_widget
, so the ThirdRound
instance does not have its manager
yet set when its __init__()
is executed, so it is still None
. Try moving the code that accesses the manager
till it is needed. Something like this:
class ThirdRound(Screen):
def __init__(self, **kwargs):
super(ThirdRound, self).__init__(**kwargs)
self.name = "thirdround"
def change_label(self, add_sub, *args): # <--- method which will change the points of the player instance
welcome_window = self.manager.get_screen('welcomewindow')
label = self.ids['testlabel']
if add_sub == 'add':
welcome_window.player1.points += 1
label.text = str(welcome_window.player1.points)
elif add_sub == 'sub':
welcome_window.player1.points -= 1
label.text = str(welcome_window.player1.points)
推荐阅读
- javascript - 关闭模式后,如何将焦点返回到单击的交互式元素?反应JS
- swagger - 如何使用springdoc-openapi / swagger生成映射到json对象的类型的可为空字段?
- apache - 重新启动apache2时出现mod_auth_form apache错误
- php - 如何将数据从控制器返回到 Laravel 中的 @include?
- c# - WrapPanel 调整大小时获取第一个子元素
- php - 项目在一个托管服务器上运行良好,但当另一个、CSS 和 jQuery 文件不工作时
- macros - clang-8 是否可以抑制音符:从宏扩展
- c# - 在代码隐藏中获取 WPF RelativeSource 绑定的值
- actionscript-3 - 获取 AS3 影片剪辑的高度给出了影片剪辑内滚动窗格的高度 - 我如何获得影片剪辑本身的高度?
- r - R 是否在寻找不存在的功能?