Meu irmão mais novo está começando a programar e, para seu projeto da Feira de Ciências, está fazendo uma simulação de um bando de pássaros no céu. Ele escreveu a maior parte de seu código e funciona muito bem, mas os pássaros precisam se mover a cada momento .
O Tkinter, no entanto, consome tempo para seu próprio loop de eventos e, portanto, seu código não será executado. Fazendo root.mainloop()
execuções, execuções e continuamente rodando, e a única coisa que executa são os manipuladores de eventos.
Existe uma maneira de ter seu código executado junto com o mainloop (sem multithreading, é confuso e deve ser mantido simples) e, se sim, qual é?
Agora mesmo, ele apareceu com um hack feio, vinculando sua move()
função a <b1-motion>
, de modo que, enquanto ele mantiver o botão pressionado e mexer o mouse, ele funcionará. Mas deve haver uma maneira melhor.
threading
módulo.A solução postada por Bjorn resulta em uma mensagem "RuntimeError: Calling Tcl from different appartment" no meu computador (RedHat Enterprise 5, python 2.6.1). Bjorn pode não ter recebido esta mensagem, pois, de acordo com um lugar que verifiquei , o manuseio incorreto do threading com o Tkinter é imprevisível e depende da plataforma.
O problema parece ser que
app.start()
conta como uma referência a Tk, uma vez que app contém elementos Tk. Consertei isso substituindoapp.start()
por umself.start()
interior__init__
. Eu também fiz isso para que todas as referências Tk estejam dentro da função que chamamainloop()
ou dentro de funções que são chamadas pela função que chamamainloop()
(isso é aparentemente crítico para evitar o erro de "apartamento diferente").Finalmente, adicionei um manipulador de protocolo com um retorno de chamada, pois sem ele o programa sai com um erro quando a janela Tk é fechada pelo usuário.
O código revisado é o seguinte:
fonte
run
método? Não consigo descobrir como ...__init__(..)
, os armazenariaself
e os usaria emrun(..)
while app.is_alive(): etc
Ao escrever seu próprio loop, como na simulação (presumo), você precisa chamar a
update
função que faz o que omainloop
faz: atualiza a janela com suas alterações, mas você o faz em seu loop.fonte
task
for chamado, você acabará com loops de evento aninhados, e isso é ruim. A menos que você entenda completamente como funcionam os loops de evento, você deve evitar chamarupdate
a todo custo.Outra opção é permitir que o tkinter seja executado em uma thread separada. Uma maneira de fazer isso é assim:
Porém, tenha cuidado, a programação multithread é difícil e é realmente fácil atirar no próprio pé. Por exemplo, você deve ter cuidado ao alterar as variáveis de membro da classe de exemplo acima, para não interromper com o loop de evento do Tkinter.
fonte
Esta é a primeira versão funcional do que será um leitor GPS e apresentador de dados. tkinter é uma coisa muito frágil, com poucas mensagens de erro. Na maior parte do tempo, não armazena coisas e não diz o porquê. Muito difícil vindo de um bom desenvolvedor de formulários WYSIWYG. De qualquer forma, ele executa uma pequena rotina 10 vezes por segundo e apresenta as informações em um formulário. Demorou um pouco para acontecer. Quando tentei um valor de timer de 0, o formulário nunca apareceu. Minha cabeça agora dói! 10 ou mais vezes por segundo é suficiente para mim. Espero que ajude outra pessoa. Mike Morrow
fonte