【问题标题】:How can I call a Kivy TextInput into my Python Function?如何将 Kivy TextInput 调用到我的 Python 函数中?
【发布时间】:2019-06-12 03:18:38
【问题描述】:

我正在尝试将来自 Kivy TextInput 小部件的文本输入调用到一个 Python 函数中,该函数将对数学进行繁重的工作,并将其输出到 TextInput 小部件旁边的标签小部件上。

我对 Kivy 很陌生,但我的教授提到了它,并且一直在搞乱它可以做什么。目前我遇到一个问题,说我试图调用的特定变量不存在。我曾尝试在 Kivy 代码中运行一个函数,该函数会将输入转换为 int 以供 Python 函数调用,但它很快就变得一团糟。在我打破我的任何进一步之前,我正在征求意见。我不会包含完整的代码,因为它很长,但这些是正在使用的 sn-ps。

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 的人来说,这应该看起来很熟悉。

编辑:我意识到少了几行。

【问题讨论】:

    标签: python python-3.x io widget kivy


    【解决方案1】:

    根本原因 - NoneType 错误

    Label 小部件实例化期间,它尝试通过调用p_strength() 方法填充Label 的文本,但Kivy 尚未完成其构建过程。因此,属性的值为 None。

    解决方案 - 绑定强度/TextInput

    解决方案是进行以下增强。

    类 AbilityDisplay(GridLayout)

    • 使用on_text_validate(当玩家按下'enter'键时)事件绑定strength/TextInput调用一个新方法on_enter()
    • 实现一个新方法on_enter() 来调用p_strength() 方法
    • 实例化Label 小部件并将其分配给self.result
    • Label(text = str(Player.p_strength())) 替换为self.result

    方法 p_strength()

    • 将参数selfstrength添加到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
    

    【讨论】:

    • 我实施了更改,但现在出现了一个新错误:文件“character_sheet.py”,第 94 行,在 p_strengthstrength_input = int(App.get_running_app().root.strength()) AttributeError: 'NoneType' 对象没有属性 'strength'
    • strength() 替换为strength.text。详情请参阅更新后的帖子。
    • 好的,我让它运行没有中断,你提供的文本有效,但我还有更多问题。在该行中:self.add_widget(Label(text = str(Player.p_strength())))。我收到非类型对象没有属性的错误。当我在 p_strength 之后取出 () 时,我得到了 repr 地址作为输出。
    • Player().p_strength()替换Player.p_strength()
    • hmmm 如果我这样做,我会得到函数的位置错误,取 0 并接收 1,但如果我只是放 Player().p_strength,我会得到:>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-11-01
    • 2018-09-19
    • 1970-01-01
    • 1970-01-01
    • 2017-12-19
    • 2017-12-31
    • 2021-11-03
    相关资源
    最近更新 更多