13

My base program imports it's GUI interface from a script GUI.py

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

In my 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)

But what It does is it opens two windows and the first window (the toplevel one) works as expected and the second is idle , This is what is expected until I click a certain button which after pressing prints data continuously and the data printed should appear in the second window's text widget however this doesn't happen and there is no response from the program and when I close the Toplevel window an error message appears

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

So How can I print the data in Text Widget rather than in the console?


EDIT:

Inorder to help ya'll if you struggling with this, I've made a script to redirect stdout to a Tkinter Text widget, see it in action here :-)

Community
  • 1
  • 1
K DawG
  • 13,287
  • 9
  • 35
  • 66
  • It may benefit you to create a [short, self-contained, runnable example](http://sscce.org/) that demonstrates your problem. There are a lot of lazy users on SO ([as there should be](http://c2.com/cgi/wiki?LazinessImpatienceHubris)), so the easier you make it to debug your program, the more answers you will receive. – Kevin Aug 29 '13 at 17:33
  • The link is 404 – Nicoolasens Apr 15 '21 at 19:02
  • 1
    @Nicoolasens Sorry man that account has been long deleted automatically with no option to recover.. You can search that name on github and it seems other people have copied portions of my code so you could recover it like that. – K DawG Apr 20 '21 at 06:04

1 Answers1

8

The problem is that when you call app.mainloop(), the thread is busy executing the Tkinter mainloop, so the statements before it are not executed until you exit the loop. But once you exit the mainloop, you try to use the Text widget but it is already destroyed.

I recommend you to move the call to main to the callback of a Tkinter widget (I suppose you are already trying to do that with app.button_press()), so the Text object can be used to display the text.

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()
A. Rodas
  • 20,171
  • 8
  • 62
  • 72