Search code examples
pythonpython-3.xtkinterwindowtoplevel

How to control display of tkinter Toplevel windows?


This is the short form of my code. In [input] window, I want it to pop up the [input2] window only and the [solve] window will pop up after I hit the button Solve!.

Currently, however, the [input2] and [solve] windows pop-up at the same time and the Solve! button doesn't do anything when it's clicked.

This is my code:

from tkinter import *

class welcome():
    def __init__(self, master): #master: root - the main window
        # welcome and introduction
        self.master=master
        self.master.geometry("500x200")

        self.welcome = Label(self.master, text="Welcome to The Bees's")
        self.welcome.pack()
        self.intro = Label(self.master, text="This is our project for Python course")
        self.intro.pack()
        self.intro2 = Label(self.master, text="This program is use for solving Linear Programming, IP, BIP, mixed... problem")
        self.intro2.pack()

        self.startbutton = Button(self.master, text="Start", bg="yellow")
        self.startbutton.pack()
        self.startbutton.config(command=self.gotoinput)

    def gotoinput(self):
        root2 = Toplevel(self.master)
        self.input1=input(root2)

Class for input window:

class input():
    def __init__(self,master):
        self.master=master
        self.master.title("Input")
        self.master.geometry("700x500")
        #cancle
        self.Canclebutton=Button(self.master,text="Cancle",command=self.master.destroy).grid(row=3,column=1)
        #OK
        self.Enterbutton=Button(self.master,text="ENTER",command=self.gotoinput2).grid(row=3,column=2)

    def gotoinput2(self):
        root3=Toplevel(self.master)
        self.input22=input2(root3)

Class for input2 window:

class input2():
    def __init__(self,master):
        self.master=master
        self.master.title("Input2")
        self.master.geometry("700x500")
        # cancle
        self.Canclebutton = Button(self.master, text="Cancle", command=self.master.destroy).grid(row=0, column=0)
        # OK
        self.Solvebutton = Button(self.master, text="Solve!", command=self.gotosolve()).grid(row=0, column=1)
        print("Through")

    def gotosolve(self):
        print("gotosolve")
        root4=Toplevel(self.master)
        self.solve11=solve(root4)

Class for Solve window:

class solve():
    def __init__(self,master):
        self.master = master
        self.master.title("Solution")
        self.master.geometry("700x500")
        # cancle
        self.Canclebutton = Button(self.master, text="Cancle", command=self.master.destroy).grid(row=0,column=0)

Main function:

def main():
    # create a main window
    root = Tk()
    root.title("The Bees's")

    b = welcome(root)
    # end line
    root.mainloop()

main()

Solution

  • As mentioned in the comments command=self.gotosolve() is the problem. It should be command=self.gotosolve.

    That said I think you should approach this a different way. Currently you are crating a toplevel window then passing that toplevel to the class. Instead you should just make the class inherit from toplevel. Same goes for welcome class. That should probably just inherit from Tk().

    Take a look at my below example that uses Tk() and Toplevel classes.

    import tkinter as tk
    
    
    class Welcome(tk.Tk):
        def __init__(self):
            tk.Tk.__init__(self)
            self.geometry("500x200")
            self.columnconfigure(0, weight=1)
            tk.Label(self, text="Welcome to The Bees's").grid(row=0, column=0)
            tk.Label(self, text="This is our project for Python course").grid(row=1, column=0)
            tk.Label(self, text="This program is use for solving Linear Programming, IP, BIP, mixed... problem").grid(row=2, column=0)
            tk.Button(self, text="Start", bg="yellow", command=lambda:Input(self)).grid(row=3, column=0)
    
    
    class Input(tk.Toplevel):
        def __init__(self, master):
            tk.Toplevel.__init__(self, master)
            self.title("Input")
            self.geometry("700x500")
            tk.Button(self, text="Cancle", command=self.destroy).grid(row=3,column=1)
            tk.Button(self, text="ENTER", command=lambda: Input2(master)).grid(row=3,column=2)
    
    
    class Input2(tk.Toplevel):
        def __init__(self, master):
            tk.Toplevel.__init__(self, master)
            self.title("Input2")
            self.geometry("700x500")
            tk.Button(self, text="Cancle", command=self.destroy).grid(row=0, column=0)
            tk.Button(self, text="Solve!", command=lambda: Solve(master)).grid(row=0, column=1)
    
    
    class Solve(tk.Toplevel):
        def __init__(self, master):
            tk.Toplevel.__init__(self, master)
            self.master.title("Solution")
            self.master.geometry("700x500")
            tk.Button(self, text="Cancle", command=self.destroy).grid(row=0,column=0)
    
    
    b = Welcome()
    

    This above example will work as you expect however I think it would probably be better to close the last top level before opening the next. Don't really want to have a bunch of windows open on top of each other. That's not difficult to manage thought so you can add it if you like.