Чтение / запись атрибутов виджета kivy с помощью python



У меня есть базовые, рабочие знания Python, которым я пытаюсь обучить себя kivy. Я бы хотел, чтобы Python мог читать и записывать данные в виджеты kivy.



Представьте, что есть приложение адресной книги, которое вставляет дату и время в текстовый ввод. Когда приложение запускается, просто попросите Python получить дату и время и вставить его правильно?



Этот программный код даст пример простой адресной книги:



from kivy.app import App

from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput

class AddressApp(App):
def build(self):
pass

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


Вот его адрес.файл kv:



GridLayout:
cols: 2
Label:
text: 'Date'
TextInput:
id: textinputdate
Label:
text: 'Time'
TextInput:
id: textinputtime
Label:
text: 'Name'
TextInput:
id: textinputname
Label:
text: 'Address'
TextInput:
id: textinputaddress
Label:
text: 'email'
TextInput:
id: textinputemail
Label:
text: 'Phone'
TextInput:
id: textinputphone


После этого, если я хотел, чтобы питон прочитал... - Не знаю... ух... номер телефона TextInput, как это сделать?

957   4  

4 ответов:

Если вы хотите, чтобы какой-то виджет имел дополнительную функциональность (например, загрузка текущей даты при запуске приложения), то создайте пользовательскую версию этого виджета, которая соответствует требованиям. А считывание значений виджетов в рамках правила очень просто. Пример:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.textinput import TextInput
from kivy.clock import Clock
import time

gui = '''
BoxLayout:
    orientation: 'vertical'

    GridLayout:
        cols: 2

        Label:
            text: 'current time'

        DateInput:
            id: date_input

    Button:
        text: 'write date to console'
        on_press: print(date_input.text)
'''


class DateInput(TextInput):

    def __init__(self, **kwargs):
        super(DateInput, self).__init__(**kwargs)
        Clock.schedule_interval(self.update, 1)  # update every second

    def update(self, dt):
        self.text = time.ctime()


class Test(App):

    def build(self):
        return Builder.load_string(gui)


Test().run()

SpinningD20 здесь. Чтобы быть справедливым, я ответил на его непосредственный вопрос, но также последовал за ним с объяснением инкапсуляции его в пользовательский виджет:

from kivy.app import App

from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput

import time


class DateInput(TextInput):
    def __init__(self, **kwargs):
        super(DateInput, self).__init__(**kwargs)
        self.text = time.strftime("%x")


class Container(GridLayout):
    def __init__(self, **kwargs):
        # using super calls the base class's init.  We'll hand it keyword arguments we received, just in case
        super(Container, self).__init__(**kwargs)
        # now we can do stuff here
        self.ids.textinputtime.text = 'from python'


class AddressApp(App):
        def build(self):
            pass

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

А в КВ:

# anything without the <> symbols is part of the App's kv.  So here's the one thing the App will have in its kv
Container:

# here's the custom widget's kv, just like your previous example
<Container>:
    cols: 2
    Label:
        text: 'Date'
    DateInput:
        id: dateinputdate
    Label:
        text: 'Time'
    TextInput:
        id: textinputtime
    Label:
        text: 'Name'
    TextInput:
        id: textinputname
    Label:
        text: 'Address'
    TextInput:
        id: textinputaddress
    Label:
        text: 'email'
    TextInput:
        id: textinputemail
    Label:
        text: 'Phone'
    TextInput:
        id: textinputphone

Надеюсь, это помогло! Удачи тебе, Дэйв!

Другой пример, объясняющий, как заполнить текстовые входные данные текущей датой через родительский макет сетки, избегая класса приложения, чтобы сохранить его чистым:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from kivy.app import App
from kivy.lang import Builder
from kivy.clock import Clock
from kivy.uix.gridlayout import GridLayout
import time

gui = '''
#:import time time
DateGrid
    cols: 1

    Label:
        text: 'Customer data'

    TextInput:
        id: date_input

    TextInput:
        id: name_input

    TextInput:
        id: email_input

    Button:
        text: 'refresh date'
        on_press: date_input.text = time.ctime()
'''


class DateGrid(GridLayout):

    def __init__(self, **kwargs):
        super(DateGrid, self).__init__(**kwargs)
        Clock.schedule_once(self.populate_inputs, 0.5)

    def populate_inputs(self, *x):
        _ = self.ids

        _.date_input.text = time.ctime()
        _.name_input.text = 'Foo Snowman'
        _.email_input.text = '[email protected]'


class Test(App):

    def build(self):
        return Builder.load_string(gui)


Test().run()

Парень по имени spinningD20 на IRC-канале FreeNode для kivy показал мне это.

Есть еще более простой способ, чем добавление пользовательского виджета. Пока вы просто хотите вставить значение в TextInput, когда приложение запускается...

Address.py

from kivy.app import App

from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput

import time

class AddressApp(App):
        def build(self):
            self.root.ids.textinputdate.text = time.strftime("%x")

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

Адрес.kv

GridLayout:
    cols: 2
    Label:
        text: 'Date'
    TextInput:
        id: textinputdate
    Label:
        text: 'Time'
    TextInput:
        id: textinputtime
    Label:
        text: 'Name'
    TextInput:
        id: textinputname
    Label:
        text: 'Address'
    TextInput:
        id: textinputaddress
    Label:
        text: 'email'
    TextInput:
        id: textinputemail
    Label:
        text: 'Phone'
    TextInput:
        id: textinputphone

Comments

    Ничего не найдено.