Как я могу вызвать Kivy TextInput в мою функцию Python? - PullRequest
0 голосов
/ 12 июня 2019

Я пытаюсь вызвать ввод текста из виджета Kivy TextInput в функцию Python, которая выполняет тяжелую работу по математике и выводит ее на виджет Label рядом с виджетом TextInput.

Я очень плохо знаком с Киви, но мой профессор упомянул об этом и возился с тем, что он может сделать.В настоящее время у меня проблема, связанная с тем, что конкретная переменная, которую я пытаюсь вызвать, не существует.Я попытался запустить функцию в коде Kivy, которая превратила бы ввод в int для вызова функции Python, но это очень быстро запуталось.Прежде чем я сломаю то, что у меня есть, я прошу совета.Я не собираюсь включать полный код, поскольку он очень длинный, но это фрагменты, которые используются.

import abilities
import races
import os
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button

class AbilityDisplay(GridLayout):

    def __init__(self, **kwargs):
        super(AbilityDisplay, self).__init__(**kwargs)
        self.cols = 3
        if os.path.isfile("character1.txt"):
            with open("character1.txt", "r") as f:
                d = f.read().split(",")
                character_name = d[0]
                char_str = d[1]

        else:
            character_name = ''
            char_str = ''

        self.add_widget(Label(text = 'Name'))
        self.name = TextInput(text = character_name, multiline = False)
        self.add_widget(self.name)
        self.add_widget(Label())
        self.add_widget(Label(text = 'Strength'))
        self.strength = TextInput(text = char_str, multiline = False) 
        self.add_widget(self.strength)
        self.add_widget(Label(text = str(Player.p_strength())))

        self.save = Button(text = 'Save')
        self.save.bind(on_press = self.save_state)
        self.add_widget(Label())
        self.add_widget(self.save)

    def save_state(self, instance):
        character_name = self.name.text
        char_str = self.strength.text

        print(f"Saving {character_name}.")

        with open("character1.txt", "w") as f:
            f.write(f"{character_name},{char_str}")


class TheApp(App):

    def build(self):
        return AbilityDisplay()


class Player():

    def p_strength():
        strength_input = int(AbilityDisplay.strength())
        racial_bonus = 0
        s_total = strength_input + racial_bonus
        s_modifier = abilities.strength(s_total)
        return s_modifier


if __name__ == '__main__':
    TheApp().run()

Есть немного больше кода, который включает в себя другие "способности", и код для математики находится в модуле способностей, который я построил.Приведенный выше код предназначен для получения входных данных игрока из виджета и запуска его через класс Player, который будет вызывать модуль способностей для математики.Тогда последний виджет метки будет отображать номер выхода.Если я введу, скажем, 18 для математики, метка должна показывать 4. Проблема в том, что я получаю код ошибки при запуске программы, который говорит, что AbilityDisplay не имеет атрибута.Мне трудно сделать эту работу, не нарушая код полностью.

Для тех, кто играет в D & D, это должно выглядеть знакомо.

Редактировать: я понял, что пропущено несколько строк.

1 Ответ

1 голос
/ 12 июня 2019

Основная причина - ошибка NoneType

Во время создания виджета Label он пытался заполнить текст Label, вызывая метод p_strength(), но Kivy не завершила процесс его построения. Следовательно, атрибуты имеют значение None.

Решение - сила привязки / TextInput

Решение состоит в том, чтобы сделать следующие улучшения.

класс AbilityDisplay (GridLayout)

  • Используйте событие on_text_validate (когда игрок нажимает клавишу «Ввод»), чтобы связать strength / TextInput, чтобы вызвать новый метод, on_enter()
  • Реализация нового метода on_enter() для вызова p_strength() метода
  • Создать Label виджет и присвоить его self.result
  • Заменить Label(text = str(Player.p_strength())) на self.result

метод p_strength ()

  • Добавить параметры, self и strength в p_strength() метод
  • Заменить AbilityDisplay.strength() на strength

Отрывки

class AbilityDisplay(GridLayout):

    def __init__(self, **kwargs):
        super(AbilityDisplay, self).__init__(**kwargs)
        self.cols = 3
        ...
        self.add_widget(Label(text='Strength'))
        self.strength = TextInput(text=char_str, multiline=False)
        self.strength.bind(on_text_validate=self.on_enter)
        self.add_widget(self.strength)

        self.result = Label()
        self.add_widget(self.result)
        ...

    def on_enter(self, instance):
        # update result's text
        self.result.text = str(Player().p_strength(instance.text))
...
class Player():

    def p_strength(self, strength):
        strength_input = int(strength)
        racial_bonus = 0
        s_total = strength_input + racial_bonus
        s_modifier = abilities.strength(s_total)
        return s_modifier
...