我在第一个屏幕中创建了某个类(播放器类)的实例,并希望在另一个屏幕中访问这些实例(及其数据)。这个想法是这样的:
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')
__init__()
的ThirdRound
方法在此行调用:
WindowManager.add_widget(ThirdRound())
特别是,ThirdRound()
在WindowManager.add_widget
之前执行,因此ThirdRound
实例在执行其manager
时尚未设置其__init__()
,因此仍为None
。尝试移动访问manager
的代码,直到需要它为止。像这样的东西:
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)