2013-08-29 3 views
5

Mes importations de programme de base, il est l'interface graphique d'un script GUI.pyComment rediriger stdout à un Tkinter widget texte

old_stdout = sys.stdout 

root = Tk.Tk() 
root.title('Coursera-dl') 
root.geometry("345x230") 
app = GUI.Interface(root) 
app.mainloop() 

if app.button_press() == True and app.return_data(): 
    data = app.return_data() 
    main(data[0],data[1],data[2],data[3],data[4],data[5],data[6],data[7],data[8]) 

sys.stdout = old_stdout 

Dans mon GUI.py:

class Interface(ttk.Frame): 
    def __init__(self,parent=None): 
     ttk.Frame.__init__(self,parent) 
     self.parent = parent 
     self.New_Window() 

    def New_Window(self): 
     self.newWindow = Tk.Toplevel(self.parent) 
     self.app = CoreGUI(self.newWindow) 


class StdoutRedirector(object): 
    def __init__(self,text_widget): 
     self.text_space = text_widget 

    def write(self,string): 
     self.text_space.insert('end', string) 
     self.text_space.see('end') 


class CoreGUI(object): 
    def __init__(self,parent): 
     self.parent = parent 
     self.InitUI() 

    def InitUI(self): 
     self.text_box = Tk.Text(self.parent, wrap='word', height = 11, width=50) 
     self.text_box.grid(column=0, row=0, columnspan = 2, sticky='NSWE', padx=5, pady=5) 
     sys.stdout = StdoutRedirector(self.text_box) 

Mais ce qu'il fait est il ouvre deux fenêtres et la première fenêtre (le toplevel) fonctionne comme prévu et la seconde est idle, C'est ce qui est attendu jusqu'à ce que je clique sur un certain bouton qui après avoir appuyé sur imprime des données en continu et les données imprimées doivent apparaître dans le second widget texte de la fenêtre mais cela ne se produit pas et il n'y a pas de réponse du programme et quand je ferme la fenêtre Toplevel un message d'erreur apparaît

"TclError: invalid command name "".33328904.33329104"""

Alors, comment puis-je imprimer les données dans le widget de texte plutôt que dans la console?


EDIT:

inorder pour YA'LL aider si vous aux prises avec cela, je l'ai fait un script pour rediriger stdout vers un widget texte Tkinter, voir en action here :-)

+0

Il peut être avantageux de créer un [exemple court, autonome et exécutable] (http://sscce.org/) qui illustre votre problème. Il y a beaucoup d'utilisateurs paresseux sur SO ([comme il se doit] (http://c2.com/cgi/wiki?LazinessImpatienceHubris)), donc plus vous facilitez le débogage de votre programme, plus vous recevrez de réponses . – Kevin

Répondre

5

Le problème est que lorsque vous appelez app.mainloop(), le thread est occupé à exécuter le Tkinter mainloop, donc les instructions avant lui ne sont pas exécutées tant que vous n'avez pas quitté la boucle. Mais une fois que vous quittez la boucle principale, vous essayez d'utiliser le widget Texte mais il est déjà détruit.

Je vous recommande de déplacer l'appel à main vers le rappel d'un widget Tkinter (je suppose que vous essayez déjà de le faire avec app.button_press()), donc l'objet Text peut être utilisé pour afficher le texte.

class CoreGUI(object): 
    def __init__(self,parent): 
     self.parent = parent 
     self.InitUI() 
     button = Button(self.parent, text="Start", command=self.main) 
     button.grid(column=0, row=1, columnspan=2) 

    def main(self): 
     print('whatever') 

    def InitUI(self): 
     self.text_box = Text(self.parent, wrap='word', height = 11, width=50) 
     self.text_box.grid(column=0, row=0, columnspan = 2, sticky='NSWE', padx=5, pady=5) 
     sys.stdout = StdoutRedirector(self.text_box) 


root = Tk() 
gui = CoreGUI(root) 
root.mainloop() 
+2

Existe-t-il un moyen de rediriger stdin? – schmi