创建一个表单以在Kivy中填充数据库

时间:2015-03-22 22:41:44

标签: python forms kivy

最终目标是使用各种小部件(textinput,复选框等)在表单中创建包含表单信息的条目。我想在表单的末尾创建一个按钮来提交对dict的响应,但是我被卡住了。我能想到的唯一方法是将所有id都设置为对象属性,然后在一个函数中单独引用它们,如series1.value ... series2.value ...

这看起来非常麻烦,以后很难在表格中添加更多条目。

这是我的.py:

from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty
from kivy.uix.checkbox import CheckBox
from kivy.uix.togglebutton import ToggleButton
from kivy.uix.button import Button


class DermRoot(BoxLayout):
    dict_filled_from_form = {}
    def add_entry_to_db(self,dict_filled_from_form):
        pass

class DemographForm(BoxLayout):
    sex = ObjectProperty()
    age_input = ObjectProperty()

    def add_entry(self,dict_of_form):
        dict_filled_from_form = dict_of_form
        #is this possible?
        #or do I have to do dict_filled_from_form['series1'] = series1.value etc

class DermApp(App):
    pass

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

和我的kv文件

DermRoot:

<DermRoot>:
    DemographForm

<DemographForm>:
    orientation: "vertical"

    GridLayout:
        age_input: age_input
        sex: sex

        cols: 2
        Label:
            text: "Patient's Age:"
        TextInput:
            id: age_input
            focus: series4
            multiline: False
        Label:
            text: "Sex:"
        ToggleButton:
            id: sex 
            text: "Male" if self.state == 'normal' else "Female"
        Label:
            text: "Standard Series to Include?"
        GridLayout:
            series1: series1
            series2: series2
            series3: series3 
            series4: series4
            series5: series5

            cols: 2
            CheckBox:
                id: series1
            Label:
                text: "Series1"
            CheckBox:
                id: series2
            Label:
                text: "Series2"
            CheckBox:
                id: series3
            Label:
                text: "series"
            CheckBox:
                id: series4
            Label:
                text: "series4"
            CheckBox:
                id: series5
            Label:
                text: "Series 5"
    Button:
        height: "40dp"
        size_hint_y: None
        text: "Add Entry to Database"
        on_press: root.add_entry(dict_of_form = 'how do I get this?')

1 个答案:

答案 0 :(得分:5)

最好的选择是使用DictProperty。尝试将一个添加到DemographForm

class DemographForm(BoxLayout):
    data = DictProperty({})

在你的kv中,你可以像这样使用它:

    Label:
        text: "Patient's Age:"
    TextInput:
        multiline: False
        # set the value from the data dict. if the key
        # doesn't exist in the dict, then use a default value
        text: root.data['age'] if 'age' in root.data else ''
        # when the value changes, update the data dict
        on_text: root.data['age'] = self.text

这也使得以后处理编辑记录变得更加容易。如果您将新的字典设置为data,它将填充表单中的所有字段。我们将edit()方法添加到DemographForm

    def edit(self, data=None):
        if data is not None:
            self.data = data
        else:
            self.data = {}  # reset the form

因此您可以填充或重置表单。你如何获得数据?有不同的方法可以做到这一点,但让我们使用一个事件。在DemographForm中,添加__events__属性和默认处理程序:

    __events__ = ('on_save', )

    def on_save(self, data):
        pass

默认处理程序不必执行任何操作。如果您创建活动,则只需要定义它。接下来我们可以将它连接到kv中的保存按钮:

    Button:
        height: "40dp"
        size_hint_y: None
        text: "Add Entry to Database"
        # dispatch our new `on_save` event
        on_press: root.dispatch('on_save', root.data)

现在你有一个on_save事件,你可以用同样的方式绑定到你的kv中:

<DermRoot>:
    DemographForm:
        # the arguments to the handler are available
        # as `args` - the last argument will be our
        # data, so we can grab it via `args[-1]`
        on_save: root.add_entry_to_db(args[-1])