tkpf é uma biblioteca para construir guis tkinter em um paradigma influenciado pelo WPF (Windows Apresentation Foundation) e Angular.
Os principais recursos são:



Você especifica a GUI no formato XML ou YAML. Aqui está um exemplo simples, 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 > Como você pode ver, os nomes de tags XML correspondem aos nomes da classe de widgets do TKINGER, enquanto o XML atribui aos seus argumentos. tkpf é opinativo, pois sempre usa os widgets com tema ttk mais bonito, quando disponíveis.
Opções como pack-anchor="nw" ou grid-row="0" especificam o layout e serão passadas para o método apropriado do Tinter Layout Manager, neste caso .pack(anchor='nw') .
Sobre como especificar uma GUI no formato YAML, consulte example/ExampleWindow.yaml .
Você exibe a GUI criando uma classe derivada da Window e mostrando -a. Você precisa fornecer o ViewModel no construtor.
class ExampleWindow ( Window ):
template_path = 'ExampleWindow.xml' # 'ExampleWindow.yaml' works too
ExampleWindow ( ExampleModel ()). show ()Se você quiser manter o Layout XML nesse arquivo embutido, também pode fazer isso:
class ExampleWindow ( Window ):
template = '<Label>Some text</Label>'ou
class ExampleWindow ( Window ):
template_yaml = '''
Label:
text: Some text
'''Definindo o título da janela:
def __init__ ( self , model ):
super (). __init__ ( model )
self . title = 'My application'Na classe View, você pode escrever manipuladores de eventos. Faça com que esse botão funcione, por exemplo:
def do_stuff ( self ):
self . combobox . config ( state = 'disabled' )Isso também mostra como você pode acessar widgets por nome nos métodos da classe de exibição. Mas se você preferir, pode acessá -los dinamicamente assim:
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 é semelhante a uma propriedade C# autogenerada. Por padrão, seu tipo de dados é str . Você pode fornecer um valor padrão ou um tipo ao seu construtor.
Bindable é um decorador que você pode usar em qualquer propriedade para retornar uma propriedade Bindable. Ele precisa saber o tipo de dados da propriedade embrulhada; portanto, especifique seu tipo de retorno com uma anotação de tipo:
@ Bindable
@ property
def foo () -> int :
return 1 AutoProperty cuida disso para você.
Somente os tipos de int , bool , float e str são suportados para ligações de Tkinter, embora, para os valores do ComboBox, você possa atribuir uma tupla de python.
Se um manipulador de eventos não for encontrado na classe de visualização, ele também será procurado no ViewModel.
No XML, você especifica a direção da ligação de dados com uma sintaxe semelhante à do angular:
values="[available_suboptions]"
é uma ligação unidirecional da fonte de dados para visualizar o destino,
textvariable="(selected_suboption)"
é uma ligação unidirecional do alvo de visualização à fonte de dados e
variable="[(choice)]"
é uma ligação de mão dupla.
Você pode usar widgets personalizados derivados das classes de widgets tkinnter. A única coisa que você precisa fazer é ligar
Directive . Registry . register ( YourCustomWidgetClass )Antes de carregar um modelo que o usa.
tkpf suporta dividir sua GUI em componentes. Aqui está um exemplo de um componente da barra de progresso com seu próprio ViewModel:
class ProgressbarModel ( ViewModel ):
value = BindableProperty ( 0 )
target = BindableProperty ( 100 )
class CustomProgressbar ( Component ):
template = '<Progressbar name="progressbar" variable="[value]" maximum="[target]"/>'E você pode usá -lo assim:
< CustomProgressbar tkpf-model = " [progressbar_model] " /> onde progressbar_model é um atributo ou propriedade no seu model de exibição principal.
No Python 3.5, você deve registrar seu componente antes de usá -lo. No Python 3.6+, que é automático.
Directive . Registry . register ( CustomProgressbar )Está planejado que você poderá adicionar atributos personalizados e vinculáveis aos componentes, como este:
class ExampleComponent ( Component ):
template = '<Label name="thelabel">Example component text</Label>'
def config ( self , ** kwargs ):
self . thelabel . config ( text = kwargs [ 'custom-text' ])E então use -os assim:
< ExampleComponent custom-text = " Custom text " />O único requisito é que o nome do atributo contenha um hífen.
tkpf suporta apenas o Python 3.5+.
Este é um trabalho em andamento. Além disso, minha primeira tentativa de criar uma biblioteca. Veja os problemas do projeto para ver o que ainda não é suportado.