Kivy - использовать текст из TextInput одного экрана на другом экране в файле .py - PullRequest
0 голосов
/ 01 апреля 2020

У меня TextInput на первом экране, и я хочу использовать полученный текст в метке на моем втором экране. Как я могу это сделать? Поскольку могут быть разные игроки, я создал класс Players, который хранит для каждого игрока имя и его / ее очки. На втором экране я также попытался создать кнопку, которая может редактировать точки (текст метки), но когда я нажимаю на нее, ничего не происходит. (Я также новичок в классах.)

В коде ниже я пометил соответствующие строки.

Итак, обзор:

  • Первый экран: извлекать имена пользователей с помощью textInput + создавать экземпляры игроков с классом Player

  • Второй экран: использовать имя игрока в метке + использовать очки игрока в метке + создавать 2 кнопки, которые складывают / вычитают точки от этой метки 'point'

Я знаю, что здесь есть похожий случай, но он не помогает мне для моего файла .py: Как проверить TextInput из один экран в другой экран в Kivy / Python?

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()

1 Ответ

0 голосов
/ 01 апреля 2020

Несколько проблем с вашим кодом:

  • Метод __init__() любого Widget вызывается при создании экземпляра этого Widget. Таким образом, метод __init__() для FirstRound вызывается в строке WindowManager.add_widget(FirstRound()). В то время нельзя было ввести текст в TextInput из WelcomeWindow, поэтому вы не можете получить имя игрока в то время.
  • Создание экземпляра Player (self.player1 = Player(name_input_player_i.text)) создает экземпляр Player до того, как пользователь сможет ввести имя игрока.
  • Использование WelcomeWindow() в методе __init__() для FirstRound создает новый экземпляр WelcomeWindow, который не связан к тому, что в вашем GUI. Поэтому любая информация, извлеченная из этого экземпляра, бесполезна.
  • В вашем FirstRound метка игровых очков получает свои данные из экземпляра класса Player во время создания Label. Изменение атрибута points Player после этого не повлияет на Label.

Первая проблема может быть решена путем перемещения большей части вашего кода из __init__() метод FirstRound и поместите его в метод on_enter(), который запускается при отображении этого Screen.

Вторая проблема может быть решена путем перемещения создания экземпляра Player в go_further(), поскольку он выполняется при выходе из WelcomeWindow.

. Третью проблему можно решить, заменив использование WelcomeWindow() на self.manager.get_screen('welcomewindow') для доступа к фактическому экземпляру WelcomeWindow, который находится в вашем GUI.

Вот модифицированная версия вашего кода, которая выполняет эти три вещи:

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()

Четвертый вопрос заслуживает отдельного вопроса, но, вероятно, связан с использованием киви язык.

...