2016-06-12 11 views
2

Ich habe eine grundlegende, praktische Kenntnisse von Python Ich versuche, mich selbst beizubringen kivy. Ich möchte Python in der Lage sein, Daten in kivy-Widgets zu lesen und zu schreiben.Lesen/schreiben kivy Widget-Attribute mit Python

Stellen Sie sich vor, es gibt eine Adressbuch-App, die Datum und Uhrzeit in einen TextInput einfügt. Wenn die App startet, Python einfach das Datum und die Uhrzeit holen und es richtig einfügen?

Dieser Programmcode wird ein Beispiel für eine einfache Adressbuch geben:

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() 

Hier ist seine address.kv Datei:

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 

Danach, wenn ich Python das gelesen haben wollte. .. Ich weiß nicht ... äh ... Telefonnummer TextInput, wie würde das gemacht werden?

Antwort

-1

Ein Typ namens spinningD20 auf dem FreeNode IRC-Kanal für Kivy zeigte mir dies.

Es gibt einen noch einfacheren Weg als ein benutzerdefiniertes Widget hinzuzufügen. Solange Sie einen Wert in das Textinput nur einfügen möchten, wenn die App startet ...

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() 

address.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 
+0

beliebigen Code Putting innen 'build' Methode, die nicht im Begriff ist, Von einem allgemeinen Verhalten der App wird dringend abgeraten. Manchmal möchten Sie Widgets in anderen Apps wiederverwenden, und diese Lösung macht es ohne unnötige weitere Umschreibungen unmöglich. Mit anderen Worten, solche Dinge sollten in benutzerdefinierte Widgets eingebettet werden, um sich in Zukunft Arbeit zu sparen. – jligeza

+0

Es hängt von der Situation ab. In diesem Fall setze ich einen Standardwert in ein TextInput. Mit anderen Worten, ich gehe durch die Anwendungskonfiguration. Ich muss keine Bibliothek von benutzerdefinierten TextInputs erstellen, und wenn ich es tue, erstelle ich ein halbes Dutzend von ihnen, die mehr Arbeit für mich selbst machen, als wenn ich beim Start einfach Werte in sie einfüge. –

+0

Dann füllen Sie sie in einem übergeordneten Widget, in diesem Fall ein Raster-Layout. Es ist nur eine gute Übung. – jligeza

1

Wenn ein Widget eine zusätzliche Funktionalität haben soll (Beispiel: Laden des aktuellen Datums beim Start der App), dann erstellen Sie eine benutzerdefinierte Version dieses Widgets, die den Anforderungen entspricht. Und das Lesen von Widgets in einer Regel ist sehr einfach. Beispiel:

#!/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() 
0

spinningD20 hier. Um fair zu sein, antwortete ich seine unmittelbare Frage, sondern auch gefolgt es mit einer Erklärung davon in eine benutzerdefinierten Widget Einkapseln:

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() 

und in kv:

# 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 

Ich hoffe, das hilft! Viel Glück Dave!

0

Ein weiteres Beispiel, zu erläutern, wie Texteingaben mit dem aktuellen Datum durch ein übergeordneten Raster-Layout zu füllen, App-Klasse zu vermeiden, dass sie sauber:

#!/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()