如何通过'on_ <property>'回调</property>将文本插入TextInput

时间:2014-05-08 22:35:27

标签: python user-interface kivy textinput

我正在使用 kivy 制作一个简单的计算器,我试图在屏幕上使用TextInput。我不确定哪个 在TextInputLabel之间会更好,但TextInput似乎是更好的选择(也许我错了?)。 GUI基本上就位,所有按钮及其各自的文本字段('0', '1', '2', '+', '=' ......等)。每一次 用户按下按钮,该按钮的文本被添加到calc_string,当&#39; =&#39;按下按钮, 将是“评估”。从本质上讲,它都可以工作,但我的输出都被打印到控制台,因为我无法获得字符串 插入TextInput屏幕。我试图在回调(TextInput)内设置screen_callback的文本 绑定到on_property的{​​{1}}方法。它不起作用。我怎样才能做到这一点?可能吗?

main.py:

TextInput

kv档案:

#!/usr/bin/env python

import kivy
kivy.require('1.8.0')
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.textinput import TextInput
from kivy.properties import ListProperty, ObjectProperty, StringProperty, NumericProperty

class Screen(TextInput):
    pass

class Calculator(BoxLayout):

    function_btns = ListProperty(['+', '-', '*', '/', '^', 'Mem <-', 'Mem ->', 'Clear'])
    digit_btns = ListProperty(['7', '8', '9', '4', '5', '6', '1', '2', '3', '0', '.', '+/-'])
    eval_string = StringProperty() # one of these strings is probably unnecessary
    calc_string = StringProperty()
    result = NumericProperty(0)

    def build_calc(self):
        # add screen textinput
        self.add_widget(Screen(text='0', multiline=False, on_calc_string=self.screen_callback))

        #create inner boxlayout to hold 2 button gridlayouts
        main_buttons_box = BoxLayout(orientation='horizontal', size_hint=(1, 0.75))

        # create 2 button gridlayouts
        digit_grid = GridLayout(cols=3, rows=4, size_hint=(0.5, 1))
        function_grid = GridLayout(cols=1, size_hint=(0.5, 1))

        # populate grids with buttons
        for i in self.digit_btns:
            digit_grid.add_widget(Button(text=str(i), on_press=self.button_callback))

        for f in self.function_btns:
            function_grid.add_widget(Button(text=str(f), on_press=self.button_callback))

        # add grids to inner boxlayout
        main_buttons_box.add_widget(digit_grid)
        main_buttons_box.add_widget(function_grid)

        # add inner boxlayout to main grid(root)
        self.add_widget(main_buttons_box)

        # finally, add boxlayout at bottom of main grid and insert equals btn
        equals_box = BoxLayout(size_hint=(1, 0.25))
        equals_box.add_widget(Button(text='=', on_press=self.button_callback))
        self.add_widget(equals_box)

    def button_callback(self, instance):
        value = instance.text
        if value == '=':
            try:
                self.result = eval(self.eval_string)
                self.calc_string = str(self.result)
                self.eval_string = ''
            except SyntaxError:
                self.calc_string = 'Error: Invalid Input'
        else:
            self.eval_string += value
            self.calc_string = self.eval_string

        print self.calc_string

    def screen_callback(self, instance):
        instance.text = self.calc_string # not working
        print 'seeing this!!!' # not working


class CalcApp(App):

    def build(self):
        calc = Calculator()
        calc.build_calc()
        return calc

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

1 个答案:

答案 0 :(得分:1)

您的Screen窗口小部件没有calc_string属性,因此on_calc_string在此处不执行任何操作:

self.add_widget(Screen(text='0', multiline=False, on_calc_string=self.screen_callback))

您需要在Calculator上绑定。 Kivy有一个有用的setter方法来帮助解决这个问题:

scr = Screen(text='0', multiline=False)
self.add_widget(scr)
self.bind(calc_string=scr.setter('text'))

此外,kv语言使这更容易。您可以用kv定义整个小部件布局...我不会重构您的整个小部件,但这是一个例子:

<Calculator>:
    orientation: 'vertical'

    Screen:
        text: root.calc_string

root指的是规则中的根小部件,此处为Calculator。每当修改root.calc_string时,Screen的{​​{1}}属性都会自动更新。