【问题标题】:How to ref a TextInput from one screen in another screen in Kivy/Python?如何在 Kivy/Python 的另一个屏幕中从一个屏幕引用 TextInput?
【发布时间】:2018-09-03 14:50:32
【问题描述】:

我正在尝试制作一个可以计算圆锥体积的应用程序(到目前为止)。 我有一个名为 ConeVolumeScreen 的屏幕,它有两个 TextInput 小部件。

<ConeVolumeScreen>:
    BoxLayout:
        orientation: ...
        padding: ...
        spacing: ...
        Label:
            text: 'Radius:'
        TextInput:
            id: cone_vol_radius
            multiline: False
            input_type: 'number'
        Label:
            text: 'Height:'
        TextInput:
            id: cone_vol_height
            multiline: False
            input_type: 'number'
        Button:
            text: 'Solve'
            on_release: app.root.changeScreen('solve cone volume')               

一个人应该在这两个小部件中输入圆锥的半径和高度。然后该人可以单击一个按钮以转到名为 SolveConeVolumeScreen 的下一个屏幕。在此屏幕中,有一个标签应打印人员指定的锥体的体积。

<SolveConeVolumeScreen>:
    BoxLayout:
        orientation: ...
        padding: ...
        spacing: ...
        Label:
            text: app.getConeVolume(cone_vol_radius, cone_vol_height)

getConeVolume() 是这里的一个方法

class CalculatorRoot(BoxLayout):
    def __init__(self, **kwargs):
        super(CalculatorRoot, self).__init__(**kwargs)
        self.screen_list = []

    def changeScreen(self, next_screen):
        if self.ids.calc_screen_manager.current not in self.screen_list:
            self.screen_list.append(self.ids.calc_screen_manager.current)

        if next_screen == 'volume':
            self.ids.calc_screen_manager.current = 'volume_screen'
        elif next_screen == 'area_screen':
            self.ids.calc_screen_manager.current = 'area_screen'
        elif next_screen == 'surface area':
            self.ids.calc_screen_manager.current = 'surfarea_screen'
        elif next_screen == 'cone volume':
            self.ids.calc_screen_manager.current = 'coneVolume_screen'
        elif next_screen == 'solve cone volume':
            self.ids.calc_screen_manager.current = 'solveConeVolume_screen'
        elif next_screen == 'rectangular based pyramid volume':
            self.ids.calc_screen_manager.current = 'rectPyramidVolume_screen'

    def onBackButton(self):
        if self.screen_list:
            self.ids.calc_screen_manager.current = self.screen_list.pop()
            return True
        return False



class CalculatorApp(App):
    def __init__(self, **kwargs):
        super(CalculatorApp, self).__init__(**kwargs)
        Window.bind(on_keyboard=self.onBackButton)

    def onBackButton(self, window, key, *args):
        if key == 27:
            return self.root.onBackButton()

    def build(self):
        return CalculatorRoot()

    def getConeVolume(self, r, h):
        first_step = 'π * ' + str(r) + '^2 * ' + str(h) + ' / 3\n'
        rr = round(r * r, 2)
        second_step = 'π * ' + str(rr) + ' * ' + str(h) + ' / 3\n'
        rh = round(rr * h, 2)
        third_step = 'π * ' + str(rh) + ' / 3\n'
        pirh = round(pi * rh, 2)
        fourth_step = str(pirh) + ' / 3\n'
        result = round(pi * rh, 2)
        final_step = 'The answer is ' + str(result) + '.'
        thing = first_step + second_step + third_step + fourth_step + final_step
        return thing

但是错误说没有定义cone_vol_radius。

 ...
 128:        spacing: min(root.width, root.height) * .02
 129:        Label:

130:文本:app.getConeVolume(cone_vol_radius, cone_vol_height) 131: 132:: ... BuilderException:解析器:文件“/Users/fayzulloh/Desktop/Calculator App/calculator.kv”,第 130 行: ... 128: 间距: min(root.width, root.height) * .02 129:标签: 130:文本:app.getConeVolume(cone_vol_radius,cone_vol_height) 131: 132:: ... NameError: 名称 'cone_vol_radius' 未定义

请帮忙。我真的很感激任何建议。

这是我的屏幕管理器

<CalculatorRoot>:
    orientation: "vertical"

    ScreenManager:
        id: calc_screen_manager
        StartScreen:
            name: 'start_screen'
        VolumeScreen:
            id: volume_screen
            name: 'volume_screen'
        AreaScreen:
            id: area_screen
            name: 'area_screen'
        SurfaceAreaScreen:
            id: surfarea_screen
            name: 'surfarea_screen'
        ConeVolumeScreen:
            id: coneVolume_screen
            name: 'coneVolume_screen'
        SolveConeVolumeScreen:
            id: solveConeVolume_screen
            name: 'solveConeVolume_screen'
        RectPyramidVolumeScreen:
            id: rectPyramidVolume_screen
            name: 'rectPyramidVolume_screen'

【问题讨论】:

    标签: python kivy nameerror


    【解决方案1】:

    错误

    应用程序中有几个错误。

    NameError - 解决方案

    root.ids.ids.coneVolume_screen.ids. 添加到参数中。

    属性错误

    解决 NameError 后,会发生 AttributeError。 AttributeError: 'NoneType' object has no attribute 'ids'。这是因为内部 id 尚不可用。

    Kivy Language » ids

    注意,在应用任何其他规则之前,最外面的小部件将 kv 规则应用于其所有内部小部件。 这意味着如果一个 内部小部件包含 id,这些 id 可能在运行期间不可用 内部小部件的__init__ 函数。

    AttributeError: ids - 解决方案

    1. 给标签一个id,例如id: result
    2. 添加on_pre_enter 事件以调用getConeVolume() 方法。
    3. 将 TextInput 对象替换为 TextInput 的文本,即将 cone_vol_radiuscone_vol_height 分别替换为 cone_vol_radius.textcone_vol_height.text
    4. 添加int()函数将TextInput的文本/字符串转换为整数。

    片段

    <SolveConeVolumeScreen>:
        on_pre_enter:
            root.ids.result.text = app.getConeVolume(int(app.root.ids.coneVolume_screen.ids.cone_vol_radius.text), int(app.root.ids.coneVolume_screen.ids.cone_vol_height.text))
    
        BoxLayout:
            orientation: 'vertical'
            Label:
                id: result
    

    输出

    【讨论】:

    • CalculatorRoot 不是 ScreenManager。但我的 CalculatorRoot 中确实有一个名为 calc_screen_manager 的 ScreenManager。查看新版本的问题。
    • 天哪,它有效。太感谢了!!!我超级感激。我无法用言语表达我的感激之情。
    猜你喜欢
    • 2020-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-09
    • 1970-01-01
    • 1970-01-01
    • 2018-03-14
    相关资源
    最近更新 更多