grauddi
grauddi

Reputation: 83

Different Windows in TKinter

I am having trouble figuring out how to run more than one application in a Tkinter instance. I am planning to have one main window that will call other applications to run.

I also want to have the login button set the username and password strings, and then close its own window.

I have already tried using Toplevel windows, but this limits my ability to format buttons. For example I cant use frames... Any help on the direction I need to take is greatly appreciated.

I am spinning my wheels trying to figure this out, I have looked at many different code samples and I keep getting contradictory ways to do the same thing. I am using python 3.

import tkinter as tk
import os
import json
from tkinter import Toplevel
cert = ""

username = ""
password = ""
base_url = ''
url = ''
splash_page = ''

class BuildApplication(tk.Frame):
    def __init__(self, master=None):
        tk.Frame.__init__(self, master)
        self.pack()
        self.createWidgets()

    def createWidgets(self):
        self.lUSER = tk.Label(self, text="Username: ").pack(side="left")
        self.eUSER = tk.Entry(self)
        self.eUSER.pack(side="left")

        self.lPASS = tk.Label(self, text="Password: ").pack(side="left")
        self.ePASS = tk.Entry(self)
        self.ePASS.pack(side="left")

        #ive tried command= lambda: self.setCredentials(self.eUSER.get(),self.ePASS.get())
        #            command = self.setCredentials(self.eUSER.get(),self.ePASS.get())
        #          But none if it works....
        self.LOGIN = tk.Button(self, text = "Login", fg="green" )
        self.LOGIN.pack(side="left")

        self.QUIT = tk.Button(self, text="QUIT", fg="red", command=self.destroy)
        self.QUIT.pack(side="left")

        self.mainloop()

    def setCredentials(self,u,p):
        username = u
        password = p
        print(username)
        print(password)
        self.destroy()

class SearchApplication(tk.Frame):
    def __init__(self, master=None):
        tk.Frame.__init__(self, master)
        self.pack()
        self.createWidgets()
    def createWidgets(self):
        print("create somethng")

class MainApplication(tk.Frame):
    def __init__(self, master=None):
        tk.Frame.__init__(self, master)
        self.pack()
        self.createWidgets()

    def createWidgets(self):        
        #Build Data
        self.bBuild = tk.Button(self, text="Build Data", command=self.build)
        self.bBuild.pack(side="top")

        #Search Data
        self.bSearch = tk.Button(self, text="Search",command=self.search)
        self.bSearch["text"] = "Search"
        self.bSearch["command"] = self.search
        self.bSearch.pack(side="top")

        #quit
        self.QUIT = tk.Button(self, text="QUIT", fg="red", command= root.destroy)
        self.QUIT.pack(side="bottom")

    def build(self):
        print("Building")
        root2 = tk.Tk()
        buildApp = BuildApplication(master=root2)
        buildApp.mainloop()

    def search(self):
        print("Search")
        root3 = tk.Tk()
        app2 = SearchApplication(master=root3)
        app2.mainloop()

root = tk.Tk()
app = MainApplication(master=root)
app.master.title("fdsafds")

app.mainloop()

Upvotes: 2

Views: 2522

Answers (1)

Marcin
Marcin

Reputation: 238131

I modified your code:

import tkinter as tk
import os
import json
from tkinter import Toplevel
cert = ""

username = ""
password = ""
base_url = ''
url = ''
splash_page = ''

class BuildApplication(tk.Frame):

    def __init__(self, master=None):
        tk.Frame.__init__(self, master)
        self.pack()
        self.createWidgets()

    def createWidgets(self):
        self.lUSER = tk.Label(self, text="Username: ")
        self.lUSER.pack(side="left") 
        self.eUSER = tk.Entry(self)
        self.eUSER.pack(side="left")

        self.lPASS = tk.Label(self, text="Password: ")
        self.lPASS.pack(side="left")
        self.ePASS = tk.Entry(self, show="*")
        self.ePASS.pack(side="left")

        #ive tried command= lambda: self.setCredentials(self.eUSER.get(),self.ePASS.get())
        #            command = self.setCredentials(self.eUSER.get(),self.ePASS.get())
        #          But none if it works....
        self.LOGIN = tk.Button(self, text = "Login", fg="green", command=self.setCredentials )
        self.LOGIN.pack(side="left")

        self.QUIT = tk.Button(self, text="QUIT", fg="red", command=self.master.destroy)
        self.QUIT.pack(side="left")

        #self.mainloop()

    def setCredentials(self):
        username = self.eUSER.get()
        password = self.ePASS.get()
        print("username", username)
        print("password", password)
        self.master.destroy()

class SearchApplication(tk.Frame):

    def __init__(self, master=None):
        tk.Frame.__init__(self, master)
        self.pack()
        self.createWidgets()

    def createWidgets(self):
        print()
        self.some_abel = tk.Label(self, text="create somethng")
        self.some_abel.pack(side="left")
        self.quitb = tk.Button(self, text = "quit", fg="green", command=self.master.destroy )
        self.quitb.pack(side="left")

class MainApplication(tk.Frame):
    def __init__(self, master=None):
        tk.Frame.__init__(self, master)
        self.pack()
        self.createWidgets()

    def createWidgets(self):        
        #Build Data
        self.bBuild = tk.Button(self, text="Build Data", command=self.build)
        self.bBuild.pack(side="top")

        #Search Data
        self.bSearch = tk.Button(self, text="Search",command=self.search)
        self.bSearch["text"] = "Search"
        self.bSearch["command"] = self.search
        self.bSearch.pack(side="top")

        #quit
        self.QUIT = tk.Button(self, text="QUIT", fg="red", command= self.master.destroy)
        self.QUIT.pack(side="bottom")

    def build(self):
        print("Building")
        root2  = tk.Toplevel()
        buildApp = BuildApplication(master=root2)


    def search(self):
        print("Search")
        root3  = tk.Toplevel()
        app2 = SearchApplication(master=root3)

root = tk.Tk()
app = MainApplication(master=root)
app.master.title("fdsafds")

app.mainloop()

The main change includes using toplevel windows in build and search methods instead of Tk() ones. You should not have multiple Tk().mainloops() in one program. Its better to use toplevel windows for new windows.

I also changed setCredentials method so that it actually works and prints out username and password and destroys its window upon pressing Login. Also I added few widgets to SearchApplication to show how to make it work.

Other problem was this line (and other lines similar to this one):

self.lUSER = tk.Label(self, text="Username: ").pack(side="left")

It does not make direct trouble in this particular code, but as a result of this line, self.lUSER is None. The reason is that pack (and grid) returns None. This might be not an issue now, but later it can save you lots of headache wondering why you cant change the label self.lUSER if you wanted to.

Below is gif showing how it works. Hope it helps.

enter image description here

Upvotes: 5

Related Questions