tkpf ist eine Bibliothek zum Aufbau von TKinter -GUIs in einem von WPF (Windows Present Foundation) und Angular beeinflussten Paradigma.
Hauptmerkmale sind:



Sie geben die GUI im XML- oder YAML -Format an. Hier ist ein einfaches Beispiel: ExampleWindow.xml :
< Frame pack-anchor = " nw " pack-padx = " 5 " >
< LabelFrame text = " Options " pack-anchor = " w " pack-fill = " x " >
< Radiobutton pack-anchor = " w " variable = " [(choice)] " value = " option1 " >
Option 1
</ Radiobutton >
< Radiobutton pack-anchor = " w " variable = " [(choice)] " value = " option2 " >
Option 2
</ Radiobutton >
< Combobox pack-anchor = " w " textvariable = " (selected_suboption) " values = " [available_suboptions] "
name = " combobox " />
< Button command = " do_stuff " >Do stuff</ Button >
</ LabelFrame >
</ Frame > Wie Sie sehen können, entsprechen die XML -Tag -Namen den Namen der Tkinter -Widget -Klasse, während XML -Namen ihre Argumente zuschreibt. tkpf ist darüber nach Meinung, dass es immer die besser aussehenden Widgets mit ttk -Themen verwendet.
Optionen wie pack-anchor="nw" oder grid-row="0" geben das Layout an und werden in diesem Fall an die entsprechende Tkinter-Layout-Manager-Methode übergeben .pack(anchor='nw') .
Unter example/ExampleWindow.yaml siehe ein GUI im YAML -Format.
Sie zeigen die GUI an, indem Sie eine vom Window abgeleitete Klasse erstellen und sie anzeigen. Sie müssen das ViewModel im Konstruktor liefern.
class ExampleWindow ( Window ):
template_path = 'ExampleWindow.xml' # 'ExampleWindow.yaml' works too
ExampleWindow ( ExampleModel ()). show ()Wenn Sie das Layout -XML in dieser Datei inline behalten möchten, können Sie dies auch tun:
class ExampleWindow ( Window ):
template = '<Label>Some text</Label>'oder
class ExampleWindow ( Window ):
template_yaml = '''
Label:
text: Some text
'''Einstellen des Fenstertitels:
def __init__ ( self , model ):
super (). __init__ ( model )
self . title = 'My application'In der View -Klasse können Sie Event -Handler schreiben. Lassen Sie diese Schaltfläche zum Beispiel funktionieren:
def do_stuff ( self ):
self . combobox . config ( state = 'disabled' )Dies zeigt auch, wie Sie in Methoden der View -Klasse mit Namen auf Widgets zugreifen können. Wenn Sie jedoch bevorzugen, können Sie dynamisch wie folgt zugreifen:
self . named_widgets [ 'combobox' ] class ExampleModel ( ViewModel ):
choice = Bindable ( AutoProperty ( 1 ))
available_suboptions = Bindable ( AutoProperty ())
selected_suboption = Bindable ( AutoProperty ())
def __init__ ( self ):
super (). __init__ ()
self . available_suboptions = ( 'suboption1' , 'suboption2' ) AutoProperty ähnelt einer autogenerierten C -Eigenschaft. Standardmäßig ist sein Datentyp str . Sie können seinen Konstruktor entweder einen Standardwert oder einen Typ angeben.
Bindable ist ein Dekorateur, den Sie auf jeder Eigenschaft verwenden können, um eine gebundene Eigenschaft zurückzugeben. Es muss den Datentyp der verpackten Eigenschaft erfahren. Geben Sie daher den Rückgabetyp mit einer Annotation des Typs an:
@ Bindable
@ property
def foo () -> int :
return 1 AutoProperty kümmert sich für Sie darum.
Nur int , bool , float und str -Typen werden für Tkinter -Bindungen unterstützt, obwohl Sie für die Combobox -Werte ein Python -Tupel zuweisen können.
Wenn ein Event -Handler nicht in der View -Klasse zu finden ist, wird er auch auf dem ViewModel nachgeschlagen.
In der XML geben Sie die Richtung der Datenbindung mit einer ähnlichen Syntax an, die der von Angular ähnelt:
values="[available_suboptions]"
ist eine Einwegbindung von Datenquelle zum Anzeigen von Target,
textvariable="(selected_suboption)"
ist eine Einwegbindung vom Ansichtsziel zur Datenquelle, und
variable="[(choice)]"
ist eine Zwei-Wege-Bindung.
Sie können benutzerdefinierte Widgets verwenden, die von Tkinter -Widget -Klassen abgeleitet wurden. Das einzige, was Sie tun müssen, ist anzurufen
Directive . Registry . register ( YourCustomWidgetClass )Vor dem Laden einer Vorlage, die sie verwendet.
tkpf unterstützt es, Ihre GUI in Komponenten zu zerlegen. Hier ist ein Beispiel für eine ProgressBar -Komponente mit einem eigenen ViewModel:
class ProgressbarModel ( ViewModel ):
value = BindableProperty ( 0 )
target = BindableProperty ( 100 )
class CustomProgressbar ( Component ):
template = '<Progressbar name="progressbar" variable="[value]" maximum="[target]"/>'Und Sie können es so verwenden:
< CustomProgressbar tkpf-model = " [progressbar_model] " /> wobei progressbar_model ein Attribut oder eine Eigenschaft auf Ihrem Hauptansichtsmodel ist.
Auf Python 3.5 müssen Sie Ihre Komponente registrieren, bevor Sie sie verwenden. Auf Python 3.6+ ist das automatisch.
Directive . Registry . register ( CustomProgressbar )Es ist geplant, dass Sie Komponenten wie folgt hinzufügen können, um benutzerdefinierte, bindbare Attribute hinzuzufügen:
class ExampleComponent ( Component ):
template = '<Label name="thelabel">Example component text</Label>'
def config ( self , ** kwargs ):
self . thelabel . config ( text = kwargs [ 'custom-text' ])Und dann benutze sie so:
< ExampleComponent custom-text = " Custom text " />Die einzige Anforderung ist, dass der Attributname einen Bindestrich enthält.
tkpf unterstützt nur Python 3.5+.
Dies ist eine laufende Arbeit. Auch mein erster Versuch, eine Bibliothek zu erstellen. Schauen Sie sich die Projektprobleme an, um zu sehen, was noch nicht unterstützt wird.