blank
blank

Reputation: 41

Function `print` does not wait for the function before it

In my Python program, I defined a function like this:

def engine_input_number_of_students_and_student_information(self, window):
        self.__input.input_number_of_students(self, window)
        print(self.number_of_students)

and the function input_number_of_students was defined in class Input like this:

class Input:
    # Function to ask user to input number of student.
    # Print error and force the user to re-input if wrong data is given.
    def input_number_of_students(self, engine, window):
        sub = tk.Toplevel(master=window)
        sub.title("Number of students")
        sub.resizable(height=False, width=False)
        window.eval(f'tk::PlaceWindow {str(sub)} center')
        frm1 = tk.Frame(master=sub)
        frm1.grid(row=0, column=0, padx=10, pady=10)
        lbl = tk.Label(text="Enter number of students:", master=frm1)
        number_of_students_var = tk.StringVar()
        ent = tk.Entry(width=3, master=frm1, textvariable=number_of_students_var)
        lbl.grid(row=0, column=0, padx=5)
        ent.grid(row=0, column=1, padx=5)
        frm2 = tk.Frame(master=sub)
        frm2.grid(row=1, column=0, sticky="nsew", padx=5, pady=5)

        def ok():
            number_of_students = int(number_of_students_var.get())
            if number_of_students < 0:
                messagebox.showinfo(message="Error: number of students must be non-negative")
                ent.delete(-1, tk.END)
            else:
                engine.number_of_students = number_of_students
                print(engine.number_of_students)
                sub.destroy()

        ok_btn = tk.Button(text="OK", master=frm2, command=ok)
        ok_btn.pack(ipadx=5, ipady=5)

But when I try to test the program, the print function was executed even when I haven't input anything for the number_of_students (it prints 0, obviously). And I don't know why.

Upvotes: 0

Views: 92

Answers (1)

kinshukdua
kinshukdua

Reputation: 1994

Your input_number_of_students doesn't wait for a user input, it creates the tkinter window, the input box and the button but it doesn't wait anywhere for the user to input something. So the program moves onto the next line which is the print line and prints a 0.

To fix this you need to call print from the callback function ok or use the wait_variable keyword.

class Input:
    # Function to ask user to input number of student.
    # Print error and force the user to re-input if wrong data is given.
    def input_number_of_students(self, engine, window):
        sub = tk.Toplevel(master=window)
        sub.title("Number of students")
        sub.resizable(height=False, width=False)
        window.eval(f'tk::PlaceWindow {str(sub)} center')
        frm1 = tk.Frame(master=sub)
        frm1.grid(row=0, column=0, padx=10, pady=10)
        lbl = tk.Label(text="Enter number of students:", master=frm1)
        number_of_students_var = tk.StringVar()
        ent = tk.Entry(width=3, master=frm1, textvariable=number_of_students_var)
        lbl.grid(row=0, column=0, padx=5)
        ent.grid(row=0, column=1, padx=5)
        frm2 = tk.Frame(master=sub)
        frm2.grid(row=1, column=0, sticky="nsew", padx=5, pady=5)

        def ok():
            number_of_students = int(number_of_students_var.get())
            if number_of_students < 0:
                messagebox.showinfo(message="Error: number of students must be non-negative")
                ent.delete(-1, tk.END)
            else:
                engine.number_of_students = number_of_students
                print(engine.number_of_students)
                sub.destroy()

        ok_btn = tk.Button(text="OK", master=frm2, command=ok)
        ok_btn.pack(ipadx=5, ipady=5)
        #I'm guessing this is the variable you modify?
        ok_btn.wait_variable(engine.number_of_students_var)

Upvotes: 1

Related Questions