2

The problem I am encountering is that I appear to be stuck in an infinite loop, (If I am not, please correct me). I am using tkinter for python 3.6 (64 bit) on windows 10.

In the module I am having an issue with I have 3 entry widgets and 2 buttons. Both buttons call the "destroy()" function in order to kill the parent window.

Below is a heavily abstracted version of my module, the purpose of the module is to take inputs from the entry widget and write them to a file.

def Create():
    parent = Tk()
    parent.MakeItlookNice
    entry1 = Entry(parent)
    entry1.insert(INSERT, "Please enter your desired username here")
    entry2 = Entry(parent)
    entry2.insert(INSERT, "Please enter your desired password here")
    entry3 = Entry(parent)
    entry3.insert(INSERT, "What is your mother's maiden name")
    Submit = tk.Button(parent,
                       text ="Click here to submit your stuff",
                       command = lambda: [parent.destroy(),
                                          submit.function()])
    Cancel = tk.Button(parent,
                       text ="Click here to cancel your request",
                       command = lambda: parent.destroy())
    parent.mainloop()

This function is contained within the module "RegisterNewUser". The "Menu" module is the module that called this function. As far as I am aware once parent.destroy() is called there is no more code to execute since it is all contained within parent.mainloop(), therefore the function is finished and the "Menu" module should continue executing.

What should happen:

  1. I want the Submit button to destroy the window, execute the function and then return to the "Menu" module.
  2. I want the cancel button to destroy the window and return to the "Menu" module.

What actually happens:

  1. The window closes, like it is supposed to
  2. But the code inside the "Menu" module does not start executing again
  3. When I go to close the python shell, it warns me that the program is still running

Ultimately my question is, what code is still running and why hasn't it stopped?

Thank you for reading this and if you require more detail please let me know.

EDIT: I have done research on this topic before posting this question. I have read the documentation on both the tk.destroy() function and the tk.mainloop() function, I have also opened up the Tkinter module in IDLE to try and understand what happens at a deeper level but after all this, I was still unable to figure out a solution. This is my first question on stack overflow, please forgive me if I have done anything wrong.

TboneSteak
  • 31
  • 5

4 Answers4

0

Hmmm, so you say multiple windows? an easier way to achieve a complex UI as such is using a concept called frames. Tkinter allows you to completely change you screen and layout if you switch to a new frames. This might require you to reprogram alot of code. for an example see Switch between two frames in tkinter Also, Some guy built a really nice Bitcoin monitoring app using tkinter and frames on youtube

Michael Ilie
  • 449
  • 2
  • 16
0

I think you would probably benefit from using Toplevel() here.

I have taken the code you provided and added it to a class used to create the main window and to manage the pop up window.

I noticed a few things with you code.

Its obvoious you are importing tkinter twice like this:

import tkinter as tk
from tkinter import *

I can tell from how you have written your entry fields vs your buttons. Do not do this. Instead just used one or the other. I recommend just using import tkinter as tk.

You are using a function to create a new tkinter instance and judging by your question you all ready have a tkinter instance created for your menu. Instead of creating new Tk() instances you can use Toplevel() instead to open a new window that can inherit everything from the main window and should be easier to manage.

You do not really need to use lambda in this situation. I have also removed the lambda function and replaced with a simple command that will work here.

Take a look at the below code and let me know if you have any questions.

import tkinter as tk


class MyApp(tk.Frame):

    def __init__(self, master, *args, **kwargs):
        tk.Frame.__init__(self, master, *args, **kwargs)
        self.master = master
        self.master.title("Main MENU")

        tk.Button(self.master, text="Open top level", command = self.create).pack()


    def create(self):
        self.top = tk.Toplevel(self.master)
        entry1 = tk.Entry(self.top, width = 35)
        entry1.pack()
        entry1.insert(0, "Please enter your desired username here")
        entry2 = tk.Entry(self.top, width = 35)
        entry2.pack()
        entry2.insert(0, "Please enter your desired password here")
        entry3 = tk.Entry(self.top, width = 35)
        entry3.pack()
        entry3.insert(0, "What is your mother's maiden name")
        tk.Button(self.top, text ="Click here to submit your stuff",
                           command = self.Submit).pack()

        tk.Button(self.top, text ="Click here to cancel your request",
                           command = self.top.destroy).pack()

    def Submit(self):
        print("Do something here to submit data")
        self.top.destroy()

if __name__ == "__main__":
    root = tk.Tk() 
    app1 = MyApp(root)
    tk.mainloop()
Mike - SMT
  • 14,784
  • 4
  • 35
  • 79
0

You can use toplevel() and its library function wait_window() just prior to (or instead of) your mainloop() and your problem will be solved

C. Peck
  • 3,641
  • 3
  • 19
  • 36
0

wait_window() mentioned above worked for me in the code below replacing popup.mainloop() with it, the mainloop() kept my code in an infinite loop upon the popup even after okay button was hit

Jason F
  • 16
  • 3