Question

Je souhaite générer un autre processus pour afficher un message d'erreur de manière asynchrone pendant que le reste de l'application se poursuit.

J'utilise le module multitraitement de Python 2.6 pour créer le processus et j'essaie d'afficher la fenêtre avec TKinter .

Ce code fonctionnait correctement sous Windows, mais si vous l'exécutiez sous Linux, la fenêtre TKinter n'apparaissait pas si j'appelais 'showerror ("Erreur MyApp", "Quelque chose de mal s'était passé." ;) '. Il apparaît si je le lance dans le même processus en appelant directement showerrorprocess . Compte tenu de cela, il semble que TKinter fonctionne correctement. Je peux imprimer sur la console et effectuer d'autres opérations à partir des processus générés par le multitraitement , de sorte que cela semble fonctionner également.

Ils ne semblent tout simplement pas fonctionner ensemble. Dois-je faire quelque chose de spécial pour permettre aux sous-processus générés de créer des fenêtres?

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()

Modifier

Le problème semble être que TKinter a été importé par le processus parent et "hérité". dans le processus enfant, mais d'une manière ou d'une autre, son état est inextricablement lié au processus parent et il ne peut pas fonctionner dans l'enfant. Tant que vous vous assurerez de ne pas importer TKinter avant de générer le processus enfant, cela fonctionnera, car c'est alors le processus enfant qui l'importera pour la première fois.

Était-ce utile?

La solution

Cette discussion pourrait être utile.

  

Voici quelques exemples de problèmes rencontrés:

     
      
  1. Bien que le module de multitraitement suive de près les threads, ce n'est certainement pas une correspondance exacte. Un exemple: depuis les paramètres à un   processus doit être picklable , je devais passer par beaucoup de code   changements pour éviter de passer des objets Tkinter , car ils ne sont pas    picklable . Cela ne se produit pas avec le module de threading.

  2.   
  3. process.terminate () ne fonctionne pas vraiment après la première tentative. La deuxième ou la troisième tentative suspend simplement l'interprète, probablement   parce que les structures de données sont corrompues (mentionnées dans l'API, mais cela   est une petite consolation).

  4.   

Autres conseils

Peut-être que l'appel de la commande shell xhost + avant d'appeler votre programme à partir de ce même shell fonctionnera?

Je suppose que votre problème réside dans le serveur X.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top