我的第一个屏幕上有一个TextInput,我想在第二个屏幕上的Label中使用收到的文本。我该怎么做?由于可以有不同的玩家,我创建了一个类玩家,为每个玩家存储一个名字和他/她的分数。在第二个屏幕中,我还尝试创建一个可以编辑点(标签的文本(的按钮,但当我单击它时,什么都没有发生。(我也是新手。(
在下面的代码中,我标记了相关行。
因此概述:
-
第一个屏幕:用textInput提取用户名+用player类创建播放器实例
-
第二个屏幕:使用标签中的玩家名称+使用标签中玩家点数+创建2个按钮,从该"点"标签中添加/减去点数
我知道这里也有类似的情况,但这对我的.py文件没有帮助:如何在Kivy/Python中从一个屏幕引用另一个屏幕的TextInput?
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"
self.layout = "layout_welcome_window"
global_layout = GridLayout(rows=3)
self.add_widget(global_layout)
label_player_i = Label(text="Name Player ")
global_layout.add_widget(label_player_i)
name_input_player_i = TextInput(id="player ", text="player", multiline=False) # <--- user inputs name here
global_layout.add_widget(name_input_player_i)
self.player1 = Player(name_input_player_i.text) # <--- name is assigned to player here
# 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):
self.manager.current = "firstround"
self.manager.transition.direction = "left"
class FirstRound(Screen):
#Give explanation of first round + option to add points for every player
def __init__(self, **kwargs):
super(FirstRound, self).__init__(**kwargs)
self.name = "firstround"
self.layout = "layout_first_round"
#Create layout
global_layout = GridLayout(rows=4)
self.add_widget(global_layout)
#Create Labels
label_player_name_i = Label(text=WelcomeWindow().player1.name) # <--- Label should get the name of the player here
global_layout.add_widget(label_player_name_i)
label_player_points_i = Label(text=str(WelcomeWindow().player1.points)) # <--- Label should get points of player
global_layout.add_widget((label_player_points_i))
#Create Buttons
button_minus = Button(text="-", font_size=100, id="minus_button")
button_minus.bind(on_release=WelcomeWindow().player1.subtract_point) # <--- When button pushed: should subtract point
global_layout.add_widget(button_minus)
button_plus = Button(text="+", font_size=100, id="plus_button")
button_plus.bind(on_release=WelcomeWindow().player1.add_point) # <--- When button pushed: should add point
global_layout.add_widget(button_plus)
WindowManager = ScreenManager()
WindowManager.add_widget(WelcomeWindow())
WindowManager.add_widget(FirstRound())
class KingenApp(App):
def build(self):
return WindowManager
if __name__ == "__main__":
KingenApp().run()
代码中的几个问题:
- 创建任何
Widget
的实例时,都会调用该Widget
的__init__()
方法。因此FirstRound
的__init__()
方法在线路WindowManager.add_widget(FirstRound())
处被调用。此时,WelcomeWindow
的TextInput
中无法输入任何文本,所以您当时无法获得玩家名称 Player
实例(self.player1 = Player(name_input_player_i.text)
(的创建在用户有机会输入玩家名称之前创建Player
实例- 在
FirstRound
的__init__()
方法中使用WelcomeWindow()
会创建一个与GUI中的实例无关的WelcomeWindow
的新实例。因此,从该实例中提取的任何信息都毫无用处 - 在
FirstRound
中,玩家点数标签在创建Label
时从Player
类实例获取数据。之后更改Player
的points
属性对Label
没有影响
第一个问题可以通过将大部分代码从FirstRound
的__init__()
方法中移出,并将其放置在显示该Screen
时运行的on_enter()
方法中来处理。
第二个问题可以通过将Player
实例的创建转移到go_further()
方法中来处理,因为它在离开WelcomeWindow
时执行。
第三个问题可以通过将WelcomeWindow()
的使用替换为self.manager.get_screen('welcomewindow')
来处理,以访问GUI中的WelcomeWindow
的实际实例。
以下是您的代码的修改版本,它可以完成以下三件事:
from kivy.app import App
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
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"
self.layout = "layout_welcome_window"
global_layout = GridLayout(rows=3)
self.add_widget(global_layout)
label_player_i = Label(text="Name Player ")
global_layout.add_widget(label_player_i)
self.name_input_player_i = TextInput(id="player ", text="player", multiline=False) # <--- user inputs name here
global_layout.add_widget(self.name_input_player_i)
# 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):
self.player1 = Player(self.name_input_player_i.text) # <--- name is assigned to player here
self.manager.current = "firstround"
self.manager.transition.direction = "left"
class FirstRound(Screen):
#Give explanation of first round + option to add points for every player
def __init__(self, **kwargs):
super(FirstRound, self).__init__(**kwargs)
self.name = "firstround"
self.layout = "layout_first_round"
def on_enter(self, *args):
#Create layout
global_layout = GridLayout(rows=4)
self.add_widget(global_layout)
#Create Labels
welcome_window = self.manager.get_screen('welcomewindow') # get a reference to the WelcomeWindow instance
label_player_name_i = Label(text=welcome_window.player1.name) # <--- Label should get the name of the player here
global_layout.add_widget(label_player_name_i)
label_player_points_i = Label(text=str(welcome_window.player1.points)) # <--- Label should get points of player
global_layout.add_widget((label_player_points_i))
#Create Buttons
button_minus = Button(text="-", font_size=100, id="minus_button")
button_minus.bind(on_release=welcome_window.player1.subtract_point) # <--- When button pushed: should subtract point
global_layout.add_widget(button_minus)
button_plus = Button(text="+", font_size=100, id="plus_button")
button_plus.bind(on_release=welcome_window.player1.add_point) # <--- When button pushed: should add point
global_layout.add_widget(button_plus)
WindowManager = ScreenManager()
WindowManager.add_widget(WelcomeWindow())
WindowManager.add_widget(FirstRound())
class KingenApp(App):
def build(self):
return WindowManager
if __name__ == "__main__":
KingenApp().run()
第四个问题应该有自己的问题,但很可能涉及到使用古怪的语言。