Opções binárias para iniciantes

tkinter — Interface Python para Tcl/Tk¶


O pacote tkinter (“Tk interface”) é a interface padrão do Python e faz parte do kit de ferramentas Tcl/Tk GUI. Tanto o Tk quanto o tkinter estão disponíveis na maioria das plataformas Unix, incluindo macOS, bem como em sistemas Windows.


Executar python -m tkinter na linha de comando deve abrir uma janela demonstrando uma interface Tk simples, informando que tkinter está apropriadamente instalado em seu sistema, e também mostrando qual versão do Tcl/Tk está instalado, para que você possa ler a documentação do Tcl/Tk específica para essa versão.


Tkinter tem suporte a uma gama de versões Tcl/Tk, compiladas com ou sem suporte a thread. O lançamento oficial do binário Python agrupa Tcl/Tk 8.6 em thread. Veja o código-fonte do módulo tkinter para mais informações sobre as versões suportadas.


O Tkinter não é um invólucro fino, mas adiciona uma boa quantidade de sua própria lógica para tornar a experiência mais pythônica. Esta documentação se concentrará nessas adições e mudanças, e consulte a documentação oficial do Tcl/Tk para detalhes que não foram alterados.


Tcl/Tk 8.5 (2007) introduziu um conjunto moderno de componentes de interface de usuário para ser usados com a nova API. As APIs antigas e novas ainda estão disponíveis. A maioria da documentação que você encontrará online ainda usa a API antiga e pode estar desatualizada.


TkDocs Um extenso tutorial sobre como criar interfaces de usuário com o Tkinter. Explica conceitos chave, e ilustra as abordagens recomendadas usando a API moderna. Referência do Tkinter 8.5: uma GUI para Python Documentação de referência para Tkinter 8.5 detalhando classes, métodos e opções disponíveis.


Comandos Tk Referência abrangente para cada um dos comandos Tcl/Tk subjacentes usados pelo Tkinter. Tcl/Tk Website Documentação adicional e links para o desenvolvimento do core do Tcl/Tk.


Modern Tkinter for Busy Python Developers Por Mark Roseman. (ISBN 978-1999149567) Python and Tkinter Programming Por Alan Moore. (ISBN 978-1788835886) Programming Python Por Mark Lutz; tem uma excelente cobertura sobre o Tkinter. (ISBN 978-0596158101) Tcl and the Tk Toolkit (2nd edition) Por John Ousterhout, criador do Tcl/Tk, e Ken Jones; não cobre o Tkinter. (ISBN 978-0321336330)


Arquitetura¶


Tcl/Tk não é uma biblioteca única mas consiste em alguns módulos distintos, cada um com sua própria funcionalidade e sua própria documentação oficial. As versões binárias do Python também incluem um módulo adicional junto com ele.


Tcl é uma linguagem de programação interpretada dinâmica, assim como Python. Embora possa ser usado sozinho como uma linguagem de programação de propósito geral, é mais comumente embutido em aplicativos C como um mecanismo de script ou uma interface para o kit de ferramentas Tk. A biblioteca Tcl tem uma interface C para criar e gerenciar uma ou mais instâncias de um interpretador Tcl, executar comandos e scripts Tcl nessas instâncias e adicionar comandos personalizados implementados em Tcl ou C. Cada interpretador tem uma fila de eventos, e há instalações para enviar eventos e processá-los. Ao contrário do Python, o modelo de execução do Tcl é projetado em torno da multitarefa cooperativa, e o Tkinter faz a ponte entre essa diferença (veja Modelo de threading para detalhes).


Tk é um pacote Tcl implementado em C que adiciona comandos personalizados para criar e manipular widgets GUI. Cada objeto Tk incorpora sua própria instância do interpretador Tcl com Tk carregado nele. Os widgets do Tk são muito personalizáveis, embora ao custo de uma aparência desatualizada. Tk usa a fila de eventos do Tcl para gerar e processar eventos da GUI.


Themed Tk (Ttk) é uma família mais recente de widgets Tk que fornecem uma aparência muito melhor em diferentes plataformas do que muitos dos widgets Tk clássicos. O Ttk é distribuído como parte do Tk, começando com o Tk versão 8.5. As ligações Python são fornecidas em um módulo separado, tkinter.ttk .


Internamente, Tk e Ttk usam recursos do sistema operacional, ou seja, Xlib no Unix/X11, Cocoa no macOS, GDI no Windows.


Quando sua aplicação Python usa uma classe do Tkinter, por exemplo, para criar um widget, o módulo tkinter primeiro monta uma sequência de comando Tcl/Tk. Ele passa essa sequência de comando Tcl para um módulo binário interno tkinter , que então chama o interpretador Tcl para avaliá-lo. O interpretador Tcl então chamará os pacotes Tk e/ou Ttk, que por sua vez farão chamadas para Xlib, Cocoa ou GDI.


Módulos Tkinter¶


O suporte para Tkinter está espalhado por vários módulos. A maioria dos aplicativos precisará do módulo tkinter principal, bem como do módulo tkinter.ttk , que fornece o conjunto de widgets temáticos modernos e a API:


from tkinter import * from tkinter import ttk.


class tkinter. Tk ( screenName = None , baseName = None , className = 'Tk' , useTk = True , sync = False , use = None ) ¶


Construa um Tk widget de alto nível, sendo esse, geralmente, a janela principal de uma aplicação, e inicialize um interpretador Tcl para esse widget. Cada instância tem seu próprio interpretador Tcl associado.


A classe Tk normalmente é instanciada usando todos os valores padrão. No entanto, os seguintes argumentos nomeados são reconhecidos atualmente:


Quando fornecido (como uma string), define a variável de ambiente DISPLAY . (Somente X11)


Nome do arquivo de perfil. Por padrão, baseName é derivado do nome do programa ( sys.argv[0] ).


Nome da classe widget. Usado como um arquivo de perfil e também como o nome com o qual Tcl é invocado ( argv0 em interp ).


Se True , inicialize o subsistema Tk. A função tkinter.Tcl() define isso como False .


Se True , execute todos os comandos do servidor X de forma síncrona, para que os erros sejam relatados imediatamente. Pode ser usado para depuração. (Somente X11)


Especifica o id da janela na qual inserir a aplicação, em vez de criá-la como uma janela de nível superior separada. O id deve ser especificado da mesma forma que o valor da opção -use para widgets de nível superior (ou seja, tem um formato como o retornado por winfo id() ).


Observe que em algumas plataformas isso só funcionará corretamente se id se referir a um frame Tk ou nível superior que tenha sua opção -container habilitada.


Tk lê e interpreta os arquivos de perfil, chamados . className .tcl e . baseName .tcl , por meio do interpretador Tcl e chama exec() no conteúdo de :file:` .py` e . baseName .py . O caminho para os arquivos de perfil encontra-se na variável de ambiente HOME ou, se não estiver definida, então os.curdir .


Objeto da aplicação Tk criado ao instanciar Tk . Isso fornece acesso ao interpretador Tcl. Cada widget anexado à mesma instância de Tk tem o mesmo valor para o atributo tk .


O objeto widget que contém este widget. Para Tk , o master é None porque é a janela principal. Os termos master e parent são semelhantes e às vezes usados alternadamente como nome de argumento; No entanto, chamar winfo parent() retorna uma string com o nome do widget enquanto master retorna o objeto. parent / child reflete a relação de árvore enquanto master / slave reflete a estrutura do contêiner.


Descendentes diretos deste widget como um dict com os nomes do widget filho como a chave e os objetos de instância filho como o valor.


tkinter. Tcl ( screenName = None , baseName = None , className = 'Tk' , useTk = False ) ¶


A função Tcl() é uma função fábrica que cria um objeto assim como o criado pela classe Tk , exceto por não inicializar o subsistema Tk. Isto é útil quando executando o interpretador Tcl em um ambiente onde não se quer criar janelas de alto nível externas, ou quando não se pode (como em sistemas Unix/Linux sem um servidor X). Um objeto criado pelo objeto Tcl() pode ter uma janela de alto nível criada (e o subsistema Tk inicializado) chamando o método loadtk() .


Os módulos que fornecem suporte ao Tk incluem:


Módulo principal Tkinter.


Caixa de diálogo para permitir que o usuário escolha uma cor.


Classe base para os diálogos definidos nos outros módulos listados aqui.


Diálogos comuns para permitir ao usuário especificar um arquivo para abrir ou salvar.


Utilitários para ajudar a trabalhar com fontes.


Acesso às caixas de diálogo padrão do Tk.


Componente de texto com uma barra de rolagem vertical integrada.


Diálogos básicos e funções de conveniência.


Conjunto de widgets temáticos introduzidos no Tk 8.5, fornecendo alternativas modernas para muitos dos widgets clássicos no módulo principal tkinter .


Um módulo binário que contém a interface de baixo nível para Tcl/Tk. Ele é importado automaticamente pelo módulo principal tkinter e nunca deve ser usado diretamente. Geralmente é uma biblioteca compartilhada (ou DLL), mas pode, em alguns casos, ser vinculada estaticamente ao interpretador Python.


Ambiente Integrado de Desenvolvimento e Aprendizagem do Python (IDLE). Baseado em tkinter .


Constantes simbólicas que podem ser usadas no lugar de strings ao passar vários parâmetros para chamadas Tkinter. Este módulo é importado automaticamente pelo módulo principal tkinter .


(experimental) Suporte de arrastar e soltar para tkinter . Será descontinuado quando for substituído pelo Tk DND.


(descontinuado) Um antigo pacote Tcl/Tk de terceiros que adiciona um número significativo de novos widgets. Melhores alternativas podem ser encontradas em tkinter.ttk .


Gráficos tartaruga em uma janela Tk.


Preservador de vida Tkinter¶


Esta seção não foi projetada para ser um tutorial exaustivo sobre Tk ou Tkinter. Para isso, consulte um dos recursos externos mencionados anteriormente. Em vez disso, esta seção fornece uma orientação muito rápida sobre como é uma aplicação Tkinter, identifica os conceitos fundamentais do Tk e explica como o wrapper do Tkinter é estruturado.


O restante desta seção ajudará a identificar as classes, métodos e opções que você precisará em uma aplicação Tkinter e onde encontrar documentação mais detalhada sobre isso, inclusive no guia de referência oficial do Tcl/Tk.


Um programa Olá Mundo¶


Começaremos a explorar o Tkinter através de uma simples aplicação “Hello World”. Esta não é a menor aplicação que poderíamos escrever, mas tem o suficiente para ilustrar alguns conceitos-chave que você precisa saber.


from tkinter import * from tkinter import ttk root = Tk () frm = ttk . Frame ( root , padding = 10 ) frm . grid () ttk . Label ( frm , text = "Hello World!" ) . grid ( column = 0 , row = 0 ) ttk . Button ( frm , text = "Quit" , command = root . destroy ) . grid ( column = 1 , row = 0 ) root . mainloop ()


Após as importações, a próxima linha será criar a instância da classe Tk que inicia Tk e cria o interpretador associado a Tcl. Ele também cria uma janela de nível superior, conhecida como janela raiz, que serve como a janela principal da aplicação.


A linha a seguir cria um frame widget , que neste caso conterá um rótulo e um botão que criaremos a seguir. O frame se encaixa dentro da janela raiz.


A próxima linha cria um rótulo widget contendo uma string de texto estático. O método grid() é utilizado para especificar o layout relativo (posição) do rótulo dentro do frame widget, semelhante a como as tabelas em HTML funcionam.


Então um widget de botão é criado, e posicionado à direita do rótulo. Quando pressionado, irá chamar o método destroy() da janela raiz.


Por fim, o método destroy() coloca tudo no display, e responde à entrada do usuário até que o programa termine.


Conceitos importantes do Tk¶


Mesmo com este programa simples, os conceitos-chave do Tk podem ser mostrados:


A interface de usuário do Tkinter é composta de widgets individuais. Cada widget é representado como um objeto Python, instanciado de classes como ttk.Frame , ttk.Label , e ttk.Button .


hierarquia dos widgets.


Os widgets são organizados em uma hierarquia . O rótulo e botão estavam contidos em um frame, que por sua vez estava contido na janela raiz. Quando criamos um widget filho , seu widget pai é passado como primeiro argumento para o construtor do widget.


opções de configuração.


Widgets possuem opções de configuração , que modificam sua aparência e comportamento, como o texto a ser exibido em um rótulo ou botão. Diferentes classes de widgets terão diferentes conjuntos de opções.


gerenciamento de geometria.


Os widgets não são automaticamente adicionados à interface de usuário quando eles são criados. Um gerenciador de geometria como grid controla onde na interface de usuário eles são colocados.


loop de eventos.


O Tkinter reage à entrada do usuário, muda de seu programa, e até mesmo atualiza a tela somente ao executar ativamente um loop de eventos . Se o seu programa não estiver executando o loop de eventos, sua interface de usuário não será atualizada.


Entendendo como Tkinter envolve Tcl/Tk¶


Quando a sua aplicação utiliza as classes e métodos do Tkinter, internamente o Tkinter está montando strings representando comandos Tcl/Tk e executando esses comandos no interpretador Tcl anexado à instância Tk de sua aplicação.


Seja tentando navegar na documentação de referência, tentando encontrar o método ou opção certa, adaptando algum código existente ou depurando seu aplicativo Tkinter, há momentos em que será útil entender como são os comandos Tcl/Tk subjacentes.


Para ilustrar, aqui está o equivalente Tcl/Tk da parte principal do script Tkinter acima.


ttk :: frame . frm - padding 10 grid . frm grid [ ttk :: label . frm . lbl - text "Hello World!" ] - column 0 - row 0 grid [ ttk :: button . frm . btn - text "Quit" - command "destroy ." ] - column 1 - row 0.


A sintaxe do Tcl é semelhante a muitas linguagens de shell, onde a primeira palavra é o comando a ser executado, seguido de argumentos para esse comando separados por espaços. Sem entrar em muitos detalhes, observe o seguinte:


Os comandos usados para criar widgets (como ttk::frame ) correspondem a classes de widgets no Tkinter. As opções de widget Tcl (como -text ) correspondem a argumentos nomeados no Tkinter. Widgets são referenciados por um pathname em Tcl (like .frm.btn ), enquanto o Tkinter não utiliza nomes, mas referências a objetos. O lugar de um widget na hierarquia widget é codificado em seu pathname (hierárquico), que utiliza um . (ponto) como um separador de caminho. O pathname para a janela raiz é apenas . (ponto). No Tkinter, a hierarquia é definida não pelo pathname, mas pela especificação do widget pai ao criar cada widget filho. Operações que são implementadas como comandos separados em Tcl (como grid ou destroy ) são representadas como métodos em objetos de widget Tkinter. Como você verá em breve, em outras ocasiões o Tcl usa o que parecem ser chamadas de método em objetos widget, que espelham mais de perto o que seria usado no Tkinter.


Como é que eu…? Que opção faz…?¶


If you’re not sure how to do something in Tkinter, and you can’t immediately find it in the tutorial or reference documentation you’re using, there are a few strategies that can be helpful.


First, remember that the details of how individual widgets work may vary across different versions of both Tkinter and Tcl/Tk. If you’re searching documentation, make sure it corresponds to the Python and Tcl/Tk versions installed on your system.


When searching for how to use an API, it helps to know the exact name of the class, option, or method that you’re using. Introspection, either in an interactive Python shell or with print() , can help you identify what you need.


To find out what configuration options are available on any widget, call its configure() method, which returns a dictionary containing a variety of information about each object, including its default and current values. Use keys() to get just the names of each option.


btn = ttk . Button ( frm , . ) print ( btn . configure () . keys ())


As most widgets have many configuration options in common, it can be useful to find out which are specific to a particular widget class. Comparing the list of options to that of a simpler widget, like a frame, is one way to do that.


print ( set ( btn . configure () . keys ()) - set ( frm . configure () . keys ()))


Similarly, you can find the available methods for a widget object using the standard dir() function. If you try it, you’ll see there are over 200 common widget methods, so again identifying those specific to a widget class is helpful.


print ( dir ( btn )) print ( set ( dir ( btn )) - set ( dir ( frm )))


Navegando no Manual de Referência Tcl/Tk¶


As noted, the official Tk commands reference manual (man pages) is often the most accurate description of what specific operations on widgets do. Even when you know the name of the option or method that you need, you may still have a few places to look.


While all operations in Tkinter are implemented as method calls on widget objects, you’ve seen that many Tcl/Tk operations appear as commands that take a widget pathname as its first parameter, followed by optional parameters, e.g.


destroy . grid . frm . btn - column 0 - row 0.


Others, however, look more like methods called on a widget object (in fact, when you create a widget in Tcl/Tk, it creates a Tcl command with the name of the widget pathname, with the first parameter to that command being the name of a method to call).


. frm . btn invoke . frm . lbl configure - text "Goodbye"


In the official Tcl/Tk reference documentation, you’ll find most operations that look like method calls on the man page for a specific widget (e.g., you’ll find the invoke() method on the ttk::button man page), while functions that take a widget as a parameter often have their own man page (e.g., grid).


You’ll find many common options and methods in the options or ttk::widget man pages, while others are found in the man page for a specific widget class.


You’ll also find that many Tkinter methods have compound names, e.g., winfo x() , winfo height() , winfo viewable() . You’d find documentation for all of these in the winfo man page.


Somewhat confusingly, there are also methods on all Tkinter widgets that don’t actually operate on the widget, but operate at a global scope, independent of any widget. Examples are methods for accessing the clipboard or the system bell. (They happen to be implemented as methods in the base Widget class that all Tkinter widgets inherit from).


Modelo de threading¶


Python e Tcl/Tk têm modelos de threading muito diferentes, que tkinter tenta fazer a ponte. Se você usa threads, pode precisar estar ciente disso.


Um interpretador Python pode ter muitas threads associados a ele. Em Tcl, várias threads podem ser criadas, mas cada thread tem uma instância de interpretador Tcl separada associada a ele. Threads também podem criar mais de uma instância do interpretador, embora cada instância do interpretador possa ser usada apenas pela thread que a criou.


Cada objeto Tk criado por tkinter contém um interpretador Tcl. Ele também controla qual thread criou aquele interpretador. Chamadas para tkinter podem ser feitas a partir de qualquer thread do Python. Internamente, se uma chamada vier de um thread diferente daquele que criou o objeto Tk , um evento é postado na fila de eventos do interpretador e, quando executado, o resultado é retornado ao thread de chamada do Python.


As aplicações Tcl/Tk são normalmente orientadas a eventos, o que significa que após a inicialização, o interpretador executa um laço de eventos (ou seja Tk.mainloop() ) e responde aos eventos. Por ser de thread única, os tratadores de eventos devem responder rapidamente, caso contrário, bloquearão o processamento de outros eventos. Para evitar isso, quaisquer cálculos de longa execução não devem ser executados em um tratador de eventos, mas são divididos em pedaços menores usando temporizadores ou executados em outra thread. Isso é diferente de muitos kits de ferramentas de GUI em que a GUI é executada em um thread completamente separado de todo o código do aplicação, incluindo tratadores de eventos.


Se o interpretador Tcl não estiver executando o laço de eventos e processando eventos, qualquer chamada tkinter feita de threads diferentes daquela que está executando o interpretador do Tcl irá falhar.


Existem vários casos especiais:


Bibliotecas Tcl/Tk podem ser construídas de forma que não reconheçam thread. Neste caso, tkinter chama a biblioteca da thread originadora do Python, mesmo que seja diferente da thread que criou o interpretador Tcl. Um bloqueio global garante que apenas uma chamada ocorra por vez. Enquanto tkinter permite que você crie mais de uma instância de um objeto Tk (com seu próprio interpretador), todos os interpretadores que fazem parte da mesma thread compartilham uma fila de eventos comum, o que fica muito rápido. Na prática, não crie mais de uma instância de Tk por vez. Caso contrário, é melhor criá-los em threads separadas e garantir que você esteja executando uma construção Tcl/Tk com reconhecimento de thread. Bloquear manipuladores de eventos não é a única maneira de evitar que o interpretador Tcl entre novamente no laço de eventos. É ainda possível executar vários laços de eventos aninhados ou abandonar totalmente o laço de eventos. Se você estiver fazendo algo complicado quando se trata de eventos ou threads, esteja ciente dessas possibilidades. Existem algumas funções de seleção do tkinter que atualmente funcionam apenas quando chamadas a partir da thread que criou o interpretador Tcl.


Referência Útil¶


Opções de Definição¶


As opções controlam coisas como a cor e a largura da borda de um widget. As opções podem ser definidas de três maneiras:


No momento da criação do objeto, usando argumentos nomeados.


fred = Button ( self , fg = "red" , bg = "blue" )