Pregunta

Quiero generar otro proceso para mostrar un mensaje de error de forma asíncrona mientras el resto de la aplicación continúa.

Estoy usando el módulo multiprocessing en Python 2.6 para crear el proceso y estoy tratando de mostrar la ventana con TKinter .

Este código funcionó bien en Windows, pero ejecutarlo en Linux, la ventana TKinter no aparece si llamo a 'showerror (" MyApp Error " ;, " Algo malo ha sucedido ". ;) '. Aparece si lo ejecuto en el mismo proceso llamando a showerrorprocess directamente. Dado esto, parece que TKinter está funcionando correctamente. Puedo imprimir en la consola y hacer otras cosas a partir de procesos generados por multiprocessing , por lo que parece estar funcionando también.

Simplemente no parecen trabajar juntos. ¿Debo hacer algo especial para permitir que los subprocesos generados creen ventanas?

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

El problema parece ser que TKinter fue importado por el proceso principal y " heredado " en el proceso hijo, pero de alguna manera su estado está inextricablemente vinculado al proceso padre y no puede funcionar en el niño. Siempre que se asegure de no importar TKinter antes de generar el proceso hijo, funcionará porque es el proceso hijo el que lo importa por primera vez.

¿Fue útil?

Solución

Esta discusión podría ser útil.

  

Aquí hay algunos problemas de muestra que encontré:

     
      
  1. Si bien el módulo de multiprocesamiento sigue de cerca los hilos, definitivamente no es una coincidencia exacta. Un ejemplo: desde parámetros a un   el proceso debe ser pickleable , tuve que pasar por un montón de código   cambios para evitar pasar objetos Tkinter ya que estos no son    pickleable . Esto no ocurre con el módulo de enhebrado.

  2.   
  3. process.terminate () realmente no funciona después del primer intento. El segundo o tercer intento simplemente cuelga al intérprete, probablemente   porque las estructuras de datos están dañadas (mencionadas en la API, pero esto   es un pequeño consuelo).

  4.   

Otros consejos

¿Tal vez llamar al comando de shell xhost + antes de llamar a su programa desde ese mismo shell funcionará?

Supongo que su problema está en el servidor X.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top