Pergunta

Eu quero gerar outro processo para exibir uma mensagem de erro de forma assíncrona, enquanto o resto do aplicativo continua.

Eu estou usando o módulo multiprocessing em Python 2.6 para criar o processo e eu estou tentando exibir a janela com TKinter.

Este código funcionou bem no Windows, mas executá-lo no Linux janela TKinter não aparecer se eu chamar 'showerror("MyApp Error", "Something bad happened.")'. É não aparecer se eu executá-lo no mesmo processo, chamando showerrorprocess diretamente. Diante disso, parece TKinter está funcionando corretamente. Posso imprimir no console e fazer outras coisas de processos gerados por multiprocessing, por isso parece estar funcionando também.

Eles simplesmente não parecem funcionar em conjunto. Preciso fazer algo especial para permitir subprocessos desovado para criar janelas?

from multiprocessing import Process
from Tkinter import Tk, Text, END, BOTH, DISABLED
import sys
import traceback

def showerrorprocess(title,text):
    """Pop up a window with the given title and text. The
       text will be selectable (so you can copy it to the
       clipboard) but not editable. Returns when the
       window is closed."""
    root = Tk()
    root.title(title)
    text_box = Text(root,width=80,height=15)
    text_box.pack(fill=BOTH)
    text_box.insert(END,text)
    text_box.config(state=DISABLED)
    def quit():
        root.destroy()
        root.quit()
    root.protocol("WM_DELETE_WINDOW", quit)
    root.mainloop()

def showerror(title,text):
    """Pop up a window with the given title and text. The
       text will be selectable (so you can copy it to the
       clipboard) but not editable. Runs asynchronously in
       a new child process."""
    process = Process(target=showerrorprocess,args=(title,text))
    process.start()

Editar

O problema parece ser que TKinter foi importado pelo processo pai, e "herdou" no processo de criança, mas de alguma forma o seu estado está intrinsecamente ligado ao processo de pai e ele não pode trabalhar na criança. Enquanto a certeza de não fazer a TKinter de importação antes de você gerar o processo filho, ele vai trabalhar, porque então é o processo filho que é importá-lo pela primeira vez.

Foi útil?

Solução

Este discussão poderia ser útil.

Eis alguns exemplos de problemas que encontrei:

  1. Enquanto o módulo de multiprocessamento segue enfiar perto, definitivamente não é uma correspondência exata. Um exemplo: uma vez que os parâmetros para a processo deve ser pickle , eu tinha que passar por um monte de código mudanças para evitar passar objetos Tkinter uma vez que estes não são pickle . Isso não ocorre com o módulo de threading.

  2. process.terminate() realmente não funciona após a primeira tentativa. A segunda ou terceira tentativa simplesmente trava o intérprete, provavelmente porque estruturas de dados estão corrompidos (mencionado na API, mas este é pouco consolo).

Outras dicas

Talvez chamando o xhost + comando shell antes de chamar o seu programa a partir dessa mesma shell vai funcionar?

Eu estou supondo que suas mentiras problema com o X-servidor.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top