4

I'm trying to do something that on the surface seem like it should be simple.

I'm executing a series of operations in Python such that one must complete before the next begins:

operation1()
operation2()
operation3()

However, operation2() requires user input from a tkinter Entry box in a popup window. Once I create this popup, operation3() executes. How do I prevent this? operation2() can create the popup and enter an indefinite loop, but a button in the popup must run a function that will break that loop. What's the best way to do this? It is important that operation2() has finished before operation3() begins.

Apologies if I'm not being clear, but I've completely confused myself trying to make this work!!!

2
  • 1
    You should make your popup modal [How to create a modal dialog in tkinter?][1] [1]: stackoverflow.com/questions/16803686/… Commented Jul 15, 2015 at 17:50
  • 1
    Why not include operation3() in the button's callback function? Commented Jul 15, 2015 at 18:46

1 Answer 1

2

One way of doing this is to make your main window (the root) wait for the popup window to run it's course.

This is accomplished by creating a popup as normal (using a Toplevel() widget I would assume), and then calling root.wait_window(theToplevel).

I've created a small example of how this is done, I think it should give you the idea.

Essentially it prompts you for an int. A popup appears upon success (call it operation 2) which prompts you for another int. After operation 2 completes, the command of the OK button of the main window changes to operation 3, which will destroy the window. However, I could also simply call op3 after the call to root.wait_window(new); this would destroy the main window once the popup finishes (or whatever op3 should do).

I've also included a for loop that simply prints a range; this is to illustrate that nothing will continue until the Toplevel has finished collecting it's data.

Here's the example code:

from Tkinter import *
from tkMessageBox import *
root = Tk()
val = 0
val2 = 0

def op1():

    global e, l, root, val, e2, b, new
    try:
        val = int(e.get())
    except ValueError:
        showerror("Error", "Enter an int")
    else:
        new = Toplevel()
        e2 = Entry(new)
        e2.pack(side = LEFT)
        b2 = Button(new, text = "OK", command = op2)
        b2.pack(side = RIGHT)
        l2 = Label(new, text = "Enter new number to multiply %d by" %val)
        l2.pack()
        e2.focus_force()
        root.wait_window(new)
        for i in range(5):
            print (i + 1)

def op2():
    global val
    try:
        val2 = int(e2.get())
    except ValueError:
        showerror("Error", "Enter an int")
        e2.focus_force()
    else:
        val = val * val2
        l.config(text = "This is your total: %d Click OK to exit" %val)
        new.destroy()
        b.config(command = op3)
def op3():
    root.destroy()

e = Entry(root)
e.pack(side = LEFT)
b = Button(root, text = "OK", command = op1)
b.pack(side = RIGHT)
l = Label(root, text = "Enter a number")
l.pack()
root.mainloop()

I hope this helps you solve your problem.

Sign up to request clarification or add additional context in comments.

2 Comments

How would I do this without using a pop-up window for the entry? Suppose the entry is in the main window and I want the focus to lock on the entry box until something is entered?
@Shihab Dider There's more than one solution to this, but one way is to disable other widgets until a valid result is detected in the entry box. I would suggest making a question so you can try find an answer tailored to your situation, as this is quite different from the question being asked.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.