简体   繁体   中英

How to correctly implement wait_window()?

import tkinter as tk

class MainWindow:

    def __init__(self, master):
        self.master = master

        self.button_height = 2
        self.button_width = 8

        self.list_of_tasks = []

        **#Other irrelevant code**

        #Button for adding a new task to current tab
        self.new_task = tk.Button(self.buttons_frame, bg="yellow", height=self.button_height, width=self.button_width*2,
                                  text="New Task",  command=self.create_new_task)
        self.new_task.grid(row=1, column=0, columnspan=2, sticky="N"+"W"+"S"+"E")

        #Frame for holding all tasks in currently selected tab
        self.tasks_in_tab = tk.Frame(master, height=300, width=300)
        self.tasks_in_tab.grid(row=2, rowspan=5, column=0, columnspan=5)

    def create_new_task(self):
        #Creates a new task
        new_window = tk.Toplevel(self.master)
        entry_window = Task_Entry(new_window)

        entry_window.wait_window(entry_window)

        task = tk.Button(self.tasks_in_tab, text=entry_window.test_entry)
        self.list_of_tasks.append(task)
        task.pack()

class Task_Entry:
    #Window for entering data into a new window
    def __init__(self, master):
        self.master = master

        self.test_entry_field = tk.Entry(self.master)
        self.test_entry_field.pack()
        self.test_entry = self.test_entry_field.get()

        self.cancel_button = tk.Button(self.master, text="Cancel", command=self.exit_program)
        self.cancel_button.pack()

    def exit_program(self):
        self.master.destroy()


root = tk.Tk()
gui = MainWindow(root)
root.mainloop()

I am attempting to use Tkinter's wait_window function in my code, but I am unsure how to properly use it in the context of where I wish to implement it.

What is suppose to happen is the user clicks the new_task button, the function create_new_task is called. This then prompts a new window, as stored under the class Task_Entry , which contains an Entry field for the user to enter text into. As soon as the user enters their input the Task_Entry window is terminated, the user input - under the test_entry field of the called Task_Entry window class - is supposed to be passed to the new Button named task .

I am pretty sure I should be using wait_window() to freeze the create_new_task function until the user has submitted their input, but I have been unable to get its implementation correct.

In addition, I believe I am incorrectly retrieving the user's input from the Task_Entry class under entry_window with get() and set() . Any clarification would also be of tremendous help there as well.

Replace:

entry_window.wait_window(entry_window)

with:

entry_window.test_entry_field.wait_window(entry_window.test_entry_field)

Because wait_window is a method for widget class objects, whereas entry_window is an object of Task_Entry which doesn't even inherit from a widget class. Which means there's no defined wait_window method for it. However, it has an attribute, test_entry_field which is a widget so there is a defined wait_window method for it.


As is, you use get too early in the code, it returns what's inside the entry in that very instant, which should be moved to right before destroying the entry, such as in callback for "Cancel" button:

def exit_program(self):
    self.test_entry = self.test_entry_field.get()
    self.master.destroy()

The code should be working the way you want it to when using the "Cancel" button:

import tkinter as tk

class MainWindow:

    def __init__(self, master):
        self.master = master

        self.button_height = 2
        self.button_width = 8

        self.list_of_tasks = []

        #Other irrelevant code**

        #Button for adding a new task to current tab
        self.new_task = tk.Button(self.master, bg="yellow",
                                height=self.button_height,
                                width=self.button_width*2,
                                text="New Task",
                                command=self.create_new_task)
        self.new_task.grid(row=1, column=0, columnspan=2,
                                sticky="N"+"W"+"S"+"E")

        #Frame for holding all tasks in currently selected tab
        self.tasks_in_tab = tk.Frame(master, height=300, width=300)
        self.tasks_in_tab.grid(row=2, rowspan=5, column=0, columnspan=5)

    def create_new_task(self):
        #Creates a new task
        new_window = tk.Toplevel(self.master)
        entry_window = Task_Entry(new_window)

        entry_window.test_entry_field.wait_window(entry_window.test_entry_field)

        task = tk.Button(self.tasks_in_tab, text=entry_window.test_entry)
        self.list_of_tasks.append(task)
        task.pack()

class Task_Entry:
    #Window for entering data into a new window
    def __init__(self, master):
        self.master = master

        self.test_entry_field = tk.Entry(self.master)
        self.test_entry_field.pack()

        self.cancel_button = tk.Button(self.master, text="Cancel",
                                command=self.exit_program)
        self.cancel_button.pack()

    def exit_program(self):
        self.test_entry = self.test_entry_field.get()
        self.master.destroy()


root = tk.Tk()
gui = MainWindow(root)
root.mainloop()

Also, note that you can't use set for an entry field itself, however, you can use insert or additionally you can assign a variable class to the entry and then be able to use set .

Wound up creating a few new functions to handle returning

def getBtn1(self):
    return self.btn1.get()
def getBtn2(self):
    return self.btn2.get()
def getBtn3(self):
    return self.btn3.get()


s = equipPopUp('Equipment Requested',staff,'N',ERI_Included='N')
s.start()
ERI = s.getBtn1()
RFRI = s.getBtn2()
rlm = s.getBtn3()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM