tkpf est une bibliothèque pour construire des GUIS Tkinter dans un paradigme influencé par WPF (Windows Presentation Foundation) et Angular.
Les principales caractéristiques sont:



Vous spécifiez l'interface graphique au format XML ou YAML. Voici un exemple simple, 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 > Comme vous pouvez le voir, les noms de balises XML correspondent aux noms de classe du widget tkinter, tandis que XML attribue à leurs arguments. tkpf est opiniâtre en ce qu'il utilise toujours les widgets sur le thème ttk les plus beaux lorsqu'ils sont disponibles.
Des options telles que pack-anchor="nw" ou grid-row="0" Spécifiez la mise en page et seront transmises à la méthode appropriée du gestionnaire de mise en page Tkinter, dans ce cas .pack(anchor='nw') .
Sur la façon de spécifier une interface graphique au format YAML, voir example/ExampleWindow.yaml .
Vous affichez l'interface graphique en créant une classe dérivée de Window et en la montrant. Vous devez fournir le ViewModel dans le constructeur.
class ExampleWindow ( Window ):
template_path = 'ExampleWindow.xml' # 'ExampleWindow.yaml' works too
ExampleWindow ( ExampleModel ()). show ()Si vous souhaitez garder la mise en page XML dans ce fichier en ligne, vous pouvez également le faire:
class ExampleWindow ( Window ):
template = '<Label>Some text</Label>'ou
class ExampleWindow ( Window ):
template_yaml = '''
Label:
text: Some text
'''Définition du titre de la fenêtre:
def __init__ ( self , model ):
super (). __init__ ( model )
self . title = 'My application'Dans la classe de vue, vous pouvez écrire des gestionnaires d'événements. Faire fonctionner ce bouton par exemple:
def do_stuff ( self ):
self . combobox . config ( state = 'disabled' )Cela montre également comment vous pouvez accéder aux widgets par nom dans les méthodes de la classe de vue. Mais si vous préférez, vous pouvez y accéder dynamiquement comme ceci:
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 est similaire à une propriété C # AutoGenerated. Par défaut, son type de données est str . Vous pouvez fournir une valeur par défaut ou un type à son constructeur.
Bindable est un décorateur que vous pouvez utiliser sur n'importe quelle propriété pour retourner une propriété liée. Il doit connaître le type de données de la propriété enveloppée, veuillez donc spécifier son type de retour avec une annotation de type:
@ Bindable
@ property
def foo () -> int :
return 1 AutoProperty s'en occupe pour vous.
Seuls les types int , bool , float et str sont pris en charge pour les liaisons Tkinter, bien que pour les valeurs ComboBox, vous pouvez affecter un tuple Python.
Si un gestionnaire d'événements n'est pas trouvé sur la classe de vue, il sera également recherché sur le ViewModel.
Dans le XML, vous spécifiez la direction de la liaison des données avec une syntaxe similaire à celle d'Angular:
values="[available_suboptions]"
est une liaison unidirectionnelle de la source de données pour afficher la cible,
textvariable="(selected_suboption)"
est une liaison à sens unique de la cible de vue à la source de données, et
variable="[(choice)]"
est une liaison bidirectionnelle.
Vous pouvez utiliser des widgets personnalisés dérivés des classes de widget tkinter. La seule chose que vous avez à faire est d'appeler
Directive . Registry . register ( YourCustomWidgetClass )Avant de charger un modèle qui l'utilise.
tkpf prend en charge la rupture de votre interface graphique en composants. Voici un exemple de composant ProgressBar avec son propre ViewModel:
class ProgressbarModel ( ViewModel ):
value = BindableProperty ( 0 )
target = BindableProperty ( 100 )
class CustomProgressbar ( Component ):
template = '<Progressbar name="progressbar" variable="[value]" maximum="[target]"/>'Et vous pouvez l'utiliser comme ceci:
< CustomProgressbar tkpf-model = " [progressbar_model] " /> où progressbar_model est un attribut ou une propriété sur votre principal ViewModel.
Sur Python 3.5, vous devez enregistrer votre composant avant de l'utiliser. Sur Python 3.6+, c'est automatique.
Directive . Registry . register ( CustomProgressbar )Il est prévu que vous pourrez ajouter des attributs d'ajout de composants personnalisés et liés, comme ceci:
class ExampleComponent ( Component ):
template = '<Label name="thelabel">Example component text</Label>'
def config ( self , ** kwargs ):
self . thelabel . config ( text = kwargs [ 'custom-text' ])Et puis utilisez-les comme ceci:
< ExampleComponent custom-text = " Custom text " />La seule exigence est que le nom d'attribut contient un trait d'union.
tkpf prend en charge uniquement Python 3.5+.
Ceci est un travail en cours. Aussi ma première tentative de création d'une bibliothèque. Regardez les problèmes du projet pour voir ce qui n'est pas encore pris en charge.