Reputation: 1
Ok, continuation of my previous question. I'm making a GUI in Tkinter where, when you press a button, another GUI is generated, where you put in some text and you press a button there and it generates some text inside a Word document. I need the user to fill out the text inputs before defining my variables, though, so that the variables aren't blank. So I'm using the threading module to do that. But, when I use the threading module, or any other way to make Python wait, the first Tkinter GUI freezes after you press a button.
import threading
import tkinter as tk
ra = threading.Event()
def function2():
import docx
from docx import Document
doc = Document("template.docx")
ra.set()
para_1 = doc.add_paragraph(variable)
para_1.add_run(" foo.")
para_1.add_run(variable2)
para_1.add_run(" beep boop.")
doc.save("example.docx")
def function1():
master = tk.Tk()
e1 = tk.Entry(master)
e1.grid(row=0, column=1)
e2 = tk.Entry(master)
e2.grid(row=1, column=1)
tk.Button(master, text="Generate", width=15, command=function2).grid(row=1)
ra.wait()
global variable
variable = (e1.get())
global variable2
variable2 = (e2.get())
r = tk.Tk()
b1 = tk.Button(r, text='example', width=25, command=function1)
b1.pack(padx=5, pady=15)
r.mainloop()
So I expected that this would run as normal, giving me a document with (not empty) variables and pre-defined strings. Problem is, when you press example
, the Tkinter GUI freezes and doesn't give you another GUI like I expect.
Upvotes: 0
Views: 192
Reputation: 386332
Everything is running in a single thread because you haven't explicitly run any of your code in a second thread. Your threading.Event
object will never be set, so your program will wait forever at the point where you call ra.wait
.
I need the user to fill out the text inputs before defining my variables, though, so that the variables aren't blank.
The way to wait for a dialog to be filled out is to use the tkinter method wait_window
which will wait for a window to be destroyed before returning. Your button needs to call a function that gets the value from the dialog and then destroy the dialog, which will cause wait_window
to return and allow your code to continue.
Also, you need to use Toplevel
, not Tk
to create additional windows.
Here is one way to use wait_window
, based on the code in your question:
import tkinter as tk
def function2():
print('variable:', variable)
print('variable2:', variable2)
def function1():
def close_dialog():
global variable, variable2
variable = e1.get()
variable2 = e2.get()
master.destroy()
master = tk.Toplevel()
e1 = tk.Entry(master)
e2 = tk.Entry(master)
b = tk.Button(master, text="Generate", width=15, command=close_dialog)
e1.grid(row=0, column=1)
e2.grid(row=1, column=1)
b.grid(row=1)
master.wait_window(master)
function2()
r = tk.Tk()
b1 = tk.Button(r, text='example', width=25, command=function1)
b1.pack(padx=5, pady=15)
r.mainloop()
Upvotes: 2