Tkinter adding Images issue - python

so I have looked about but cant find anything that works for me so if I add a image to my first page (log in page) the image will display fine. However if I try and add it to my main page I get the error pyimage 1
Here is the code: (I've tried to remove all the code not needed to shorten it)
import tkinter as tk
from tkinter import ttk
from tkinter import Scrollbar, messagebox
import os
from PIL import ImageTk,Image
global appcwd
appcwd = os.getcwd()
class Login_Start(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
main_frame = tk.Frame(self, bg="black", height=768, width=1366)
main_frame.pack(fill="both", expand="true")
self.geometry("1366x768")
#INSERTING IMAGE HERE
#path = "{}\\grem.png".format(appcwd)
#img = ImageTk.PhotoImage(Image.open(path))
#pic2lab = tk.Label(main_frame, image=img)
#pic2lab.photo = img
#pic2lab.pack()
loginbut = tk.Button(main_frame, width=10, text='Login', command=lambda: Get_Login())
loginbut.pack()
def Get_Login():
validation = True
if validation:
root.deiconify()
top.destroy()
else:
tk.messagebox.showerror("Information", "The details are either wrong or you need to register")
class MenuBar(tk.Menu):
def __init__(self, parent):
tk.Menu.__init__(self, parent)
menu_file = tk.Menu(self, tearoff=0)
self.add_cascade(label="File", menu=menu_file)
menu_file.add_command(label="Main Menu", command=lambda: parent.show_frame(Main_Page))
class App(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
main_frame = tk.Frame(self, bg="grey", height=768, width=1366)
main_frame.pack_propagate(0)
main_frame.pack(fill="both", expand="true")
main_frame.grid_rowconfigure(0, weight=1)
main_frame.grid_columnconfigure(0, weight=1)
self.geometry("1366x768")
self.frames = {}
pages = (Main_Page, Admin_Page)
for F in pages:
frame = F(main_frame, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(Main_Page)
menubar = MenuBar(self)
tk.Tk.config(self, menu=menubar)
def show_frame(self, name):
frame = self.frames[name]
frame.tkraise()
class Temp(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.main_frame = tk.Frame(self, bg="black", height=768, width=1366)
self.main_frame.pack_propagate(0)
self.main_frame.pack(fill="both", expand="true")
self.main_frame.grid_rowconfigure(0, weight=1)
self.main_frame.grid_columnconfigure(0, weight=1)
self.main = tk.LabelFrame(self.main_frame, bg='black')
self.main.place(relx=0.01, rely=0.21, height=490, width=1330)
class Main_Page(Temp):
def __init__(self, parent, controller):
Temp.__init__(self, parent)
mainlabel = tk.Label(self.main, font=("Trebuchet MS Bold", 16), bg="grey", fg="black", text="TEXT")
mainlabel.pack()
path = "{}\\grem.png".format(appcwd)
img = ImageTk.PhotoImage(Image.open(path))
pic2lab = tk.Label(self.main, image=img)
pic2lab.photo = img
pic2lab.pack()
butbut = tk.Button(self.main, text="press", command=lambda:controller.show_frame(Admin_Page))
butbut.pack()
class Admin_Page(Temp):
def __init__(self, parent, controller):
Temp.__init__(self, parent)
hm = tk.Label(self.main, bg="grey", fg='black', text='Admin_Page')
hm.place(rely=0.02, relx=0.01,)
top = Login_Start()
top.title("main title")
root = App()
root.withdraw()
root.title("main title")
root.mainloop()
Like I said works fine in the Login_Start() Class but won't in the Main_Page()

Related

i want to pass a variable from one class to another and use it in Label widget using python and tkinter

I want to pass variable n from startpage to page1. Then put the variable into a label widget called label_country. How can I do this within tkinter? I tried calling the variable by the class and I also used the n.get() method.
import tkinter as tk
from tkinter import ttk
class tkinterApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
container = tk.Frame(self, height=1000, width=1000, bg="gray")
container.pack(side="top", fill="both", expand=True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in (StartPage, Page1):
frame = F(container, self)
self.frames[F] = frame
frame.place(relx=0, rely=0, relwidth=1, relheight=1)
self.show_frame(StartPage)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent, bg="gray")
style = ttk.Style()
style.configure('W.TButton', foreground='black', background='white'
)
button = ttk.Button(self, text="slect a country ", style='W.TButton',
command=lambda: [ controller.show_frame(Page1)])
button.place(relx=0.66, rely=0.05, relwidth=0.2, relheight=0.07)
ttk.Label(self, text="country slect:").place(relx=0.14, rely=0.05, relwidth=0.5, relheight=0.07)
n = tk.StringVar()
country_choice = ttk.Combobox(self, width=27, textvariable=n)
country_choice["values"] = ([x for x in df["Country"].unique()])
country_choice.place(relx=0.14, rely=0.05, relwidth=0.5, relheight=0.07)
country_choice.current()
text_box = tk.Text(self, height=28, width=30, bg="white")
text_box.insert(tk.INSERT, "INFORMATIONT ABOUT THE PROGRAM")
text_box.config(state="disabled")
text_box.place(relx=0.14, rely=0.15, )
class Page1(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent, bg="gray")
label_country = tk.Label(self, text= StartPage.n, bg = "white")
label_country.place(relx=0.795, rely=0.13, relwidth=0.0755, relheight=0.03)
app = tkinterApp()
app.mainloop()

How to prevent multiple windows from popping up in tkinter?

import tkinter as tk
from tkinter import *
from tkinter import ttk
LARGE_FONT = ("Verdana", 12)
class pages(tk.Tk):
#starts us off in the login page
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
tk.Tk.wm_title(self, "ScanNET")
tk.Tk.wm_minsize(self, 800, 800)
container = tk.Frame(self)
container.pack(side=TOP, fill=BOTH, expand=True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in (loginpage, GUI):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky=N+E+S+W)
self.show_frame(loginpage)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class loginpage(tk.Frame):
#login page content
def __init__(self, parent, controller):
tk.Frame.__init__(self,parent)
loginlabel = tk.Label(self, text="login page", font=LARGE_FONT)
loginlabel.pack(padx=10, pady=10)
#button moves you to gui
loginbutton1 = tk.Button(self, text= "Go to GUI", command=lambda: controller.show_frame(GUI))
loginbutton1.pack()
class GUI(tk.Frame):
def __init__(self, parent, controller):
#all widths and heights aren't official, most likely change
tk.Frame.__init__(self, parent)
self.root = tk.Tk()
#the tabs
my_notebook = ttk.Notebook(self.root)
my_notebook.pack()
devicestab = Frame(my_notebook, width=800, height=600)
reportstab = Frame(my_notebook, width=800, height=600)
devicestab.pack(fill=BOTH, expand=1)
reportstab.pack(fill=BOTH, expand=1)
my_notebook.add(devicestab, text="Devices")
my_notebook.add(reportstab, text="Reports")
#contents for devices tab
devicesleft = LabelFrame(devicestab, text="Devices found: ", padx=5, pady=5, width=500, height=600)
devicesleft.grid(row=0, column=0)
devicesright = LabelFrame(devicestab, text="Activity Feed: ", padx=5, pady=5, width=300 , height=600)
devicesright.grid(row=0, column=1)
#contents for reports tab
reportsleft = LabelFrame(reportstab, text="Report Summaries: ", padx=5, pady=5, width=400 , height=600)
reportsleft.grid(row=0, column=0)
reportsright= LabelFrame(reportstab, text="Charts and Diagrams: ", padx=5, pady=5, width=400 , height=600)
reportsright.grid(row=0, column=1)
app = pages()
app.mainloop()
When I run this, both the loginpage and GUI windows open. Correct me if I'm wrong, but I think the problem is probably around the
tk.Frame.__init__(self, parent)
self.root = tk.Tk()
my_notebook = ttk.Notebook(self.root)
part in the GUI class. I've searched everywhere and I can't seem to find a way to have a first page as a login page which will move to a second page that has tabs using notebook. I feel as if something else has to be in the ttk.Notebook() part, and perhaps remove self.root = tk.Tk() after. I'd love to hear what y'all think.
I am assuming you want the notebook in the same widget of the rest, so you should not use tk.Tk() and then you place the notebook in the parent which is already your root. Check the code in the end of my answer. Also, since there was a lot of problems with your code I made some changes and comments that will help you to write better codes in tkinter. Please read it carefully. You may also want to study the effbot web page.
import tkinter as tk
# from tkinter import * # just don't do this
from tkinter import ttk
LARGE_FONT = ("Verdana", 12)
# class pages(tk.Tk):
class Pages(tk.Tk): # class names should start with upper case
#starts us off in the login page
# def __init__(self, *args, **kwargs):
def __init__(self):
# tk.Tk.__init__(self, *args, **kwargs)
tk.Tk.__init__(self)
# tk.Tk.wm_title(self, "ScanNET")
self.winfo_toplevel().title("ScanNET")
# tk.Tk.wm_minsize(self, 800, 800)
self.wm_minsize(800, 800) # since you defined tk.Tk as pages parent you can call Tk methods directly
container = tk.Frame(self)
# container.pack(side=TOP, fill=BOTH, expand=True)
# container.grid_rowconfigure(0, weight=1)
# container.grid_columnconfigure(0, weight=1)
container.grid(row=0, column = 0) # don't use pack if you want to use grid
self.frames = {}
for F in (loginpage, GUI):
frame = F(container, self)
self.frames[F] = frame
# frame.grid(row=0, column=0, sticky=N+E+S+W)
frame.grid(row=0, column=0, sticky='NESW') #since we are not importing all we are not importing tk.W but you can use string instead
self.show_frame(loginpage)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class loginpage(tk.Frame):
#login page content
def __init__(self, parent, controller):
tk.Frame.__init__(self,parent)
loginlabel = tk.Label(self, text="login page", font=LARGE_FONT)
loginlabel.pack(padx=10, pady=10)
#button moves you to gui
loginbutton1 = tk.Button(self, text= "Go to GUI", command=lambda: controller.show_frame(GUI))
loginbutton1.pack()
class GUI(tk.Frame):
def __init__(self, parent, controller):
#all widths and heights aren't official, most likely change
tk.Frame.__init__(self, parent)
# self.root = tk.Tk() # don't create new Tk objects, you just need one. The others should be Toplevel objects
### self.root = tk.Toplevel() ### this would be the correct way of creating a new window but you don't want to do that here your root is your parent
#the tabs
# my_notebook = ttk.Notebook(self.root)
my_notebook = ttk.Notebook(self) # this is how you place the notebook in the Frame widget and not in a new one
# my_notebook.pack()
my_notebook.grid() # we are now using grid so it will not accept pack anymore
# devicestab = Frame(my_notebook, width=800, height=600)
devicestab = tk.Frame(my_notebook, width=800, height=600) # again, since we are not importing al we have to use tk. before tkinter methods
# reportstab = Frame(my_notebook, width=800, height=600)
reportstab = tk.Frame(my_notebook, width=800, height=600)
# devicestab.pack(fill=BOTH, expand=1)
devicestab.pack(fill="both", expand=1) # instead of tk.BOTH we can use "both"
reportstab.pack(fill="both", expand=1)
my_notebook.add(devicestab, text="Devices")
my_notebook.add(reportstab, text="Reports")
#contents for devices tab
devicesleft = tk.LabelFrame(devicestab, text="Devices found: ", padx=5, pady=5, width=500, height=600)
devicesleft.grid(row=0, column=0)
devicesright = tk.LabelFrame(devicestab, text="Activity Feed: ", padx=5, pady=5, width=300 , height=600)
devicesright.grid(row=0, column=1)
#contents for reports tab
reportsleft = tk.LabelFrame(reportstab, text="Report Summaries: ", padx=5, pady=5, width=400 , height=600)
reportsleft.grid(row=0, column=0)
reportsright= tk.LabelFrame(reportstab, text="Charts and Diagrams: ", padx=5, pady=5, width=400 , height=600)
reportsright.grid(row=0, column=1)
app = Pages()
app.mainloop()

Tkinter variable value is not passed to other class

I have a little bit of strange problem and I will try to explain.
So I am trying to connect to WiFi through tkinter, and I am passing variables like name of the WiFi and the password, between classes, and its working. I know this because I am displaying them in Labels, but when I try to connect to WiFi, the variables are not passed as arguments to the connection string.
Here is part of my code :
import tkinter as tk
from PIL import Image, ImageTk
import time
import os
from wifi import Cell, Scheme
LARGE_FONT = ("Verdana", 12)
from tkinter import END
class SeaofBTCapp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
container = tk.Frame(self)
self.geometry("480x800")
self.label = tk.Label(text="This is the start page",background="blue",height=2)
self.label.pack(side="top", fill="x", pady=0)
self.time1 = ''
self.time2 = time.strftime('%H:%M:%S')
self.watch = tk.Label(self, text=self.time2, font=('times', 12, 'bold'))
self.watch.pack()
self.changeLabel() #first call it manually
self.a=tk.StringVar()
self.passcode=tk.StringVar()
container.pack(side="top", fill="both", expand=True)
container.grid_rowconfigure(0, weight=100)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in (SetUpPage,ChoseWIFI,TypePassword,Connecting):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(SetUpPage)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
def changeLabel(self):
self.time2 = time.strftime('%H:%M:%S')
self.watch.configure(text=self.time2)
self.after(200, self.changeLabel) # it'll call itself continuously
class SetUpPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
image = Image.open("wifi_icon.gif")
image = image.resize((50, 50), Image.ANTIALIAS)
self.reset_img = ImageTk.PhotoImage(image)
image1 = Image.open("ethernet_icon.gif")
image1 = image1.resize((50, 50), Image.ANTIALIAS)
self.reset_img1 = ImageTk.PhotoImage(image1)
self.but = tk.Button(self, text="WORK IN", height=180, width=180, image=self.reset_img,command=lambda: controller.show_frame(ChoseWIFI)).place(x=150, y=125)
self.but1 = tk.Button(self, text="WORK OUT", height=180, width=180, image=self.reset_img1).place(x=150, y=425)
class ChoseWIFI(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller=controller
self.mylistbox=tk.Listbox(self,width=80,height=10,font=('times',13))
self.mylistbox.bind('<<ListboxSelect>>',self.CurSelet)
self.mylistbox.place(x=100,y=190)
self.wifiscan()
self.but = tk.Button(self, text="CONNECT", height=10, width=10,command=lambda: controller.show_frame(TypePassword)).place(x=150, y=525)
def wifiscan(self):
allSSID = [cell.ssid for cell in Cell.all('wlan0')]
print (allSSID )# prints all available WIFI SSIDs
for i in range(len(allSSID )):
if print(str(allSSID [i]))== print(myssid):
a = i
print("hit")
myssidA = allSSID [a]
print( myssidA )
break
else:
print ("getout")
print (myssid)
self.itemsforlistbox=allSSID
for items in self.itemsforlistbox:
self.mylistbox.insert(END,items)
def CurSelet(self,a):
value=self.mylistbox.get(self.mylistbox.curselection())
self.o=self.controller.a
self.o.set(value)
class TypePassword(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller=controller
#self.entry1 = tk.Label(self, textvariable=self.controller.shared_data["username"])
#self.entry1.pack()
self.L2 = tk.Label(self, textvariable=self.controller.a)
self.L2.pack()
self.L1 = tk.Label(self, text="Type password")
self.L1.pack()
self.E1 = tk.Entry(self, bd=5)
self.E1.place(x=150, y=325)
#self.connect()
self.but = tk.Button(self, text="CONNECT", height=10, width=10,command=lambda:[self.connect(), controller.show_frame(Connecting)]).place(x=150, y=525)
def connect(self):
self.controller.passcode.set(self.E1.get())
#os.system('nmcli d wifi connect "%s" password %s iface %s' % (self.controller.a,self.controller.passcode, self.controller.a)) # vive1234 is the password to my wifi myssidA is the wifi name
self.pas=self.controller.passcode
self.passw = self.E1.get()
self.pas.set(self.passw)
class Connecting(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller=controller
self.entry1 = tk.Label(self, text="CONNECTING.....")
self.entry1.pack()
self.entry2 = tk.Label(self, textvariable=self.controller.a)
self.entry2.pack()
self.entry3 = tk.Label(self, textvariable=self.controller.passcode)
self.entry3.pack()
self.but = tk.Button(self, text="CONNECT11", height=10, width=10,command=self.k).place(x=150, y=525)
#self.but.tk.bind(('<but>', self.k))
def k(self):
#connection string for WIFI
os.system('nmcli d wifi connect "%s" password %s iface %s' % (self.controller.a,self.controller.passcode, self.controller.a)) # vi
print("KKKK")
if __name__ == "__main__":
# Calls its attribute.
app = SeaofBTCapp()
a=app.changeLabel()
app.after(200,a )
# Calls its attribute.
app.mainloop()

How to keep a constant layout in multiple windows Tkinter program?

I am working on a Python Tkinter application which is expected to have multiple windows. At the same time, I would like to keep certain layout (background image, Top/bottom labels) constant. I have tried to set the background image (b_image) and top left label (topleft_label ) but it's not showing up. Can someone look at this snippet and advise how to achieve this?
import tkinter as tk
LARGE_FONT= ("Verdana", 12)
HEIGHT = 768
WIDTH = 1024
class MainApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.title("Sales System") # set the title of the main window
self.geometry("%dx%d+0+0" % (WIDTH, HEIGHT)) # set size of the main window to 300x300 pixels
container = tk.Frame(self)
b_image = tk.PhotoImage(file='background.png')
b_label = tk.Label(container, image=b_image)
b_label.place(relwidth=1, relheight=1)
topleft_label = tk.Label(container, bg='black', fg='white', text="Welcome - Login Screen", justify='left', anchor="w", font="Verdana 12")
topleft_label.place(relwidth=0.5, relheight=0.05, relx=0.25, rely=0, anchor='n')
container.pack(side="top", fill="both", expand = True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
frame = StartPage(container, self)
self.frames[StartPage] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(StartPage)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self,parent)
label = tk.Label(self, text="Start Page", font=LARGE_FONT)
label.pack(pady=10,padx=10)
app = MainApp()
app.mainloop()
The approach
The best way of going about this is most likely be to make a base_frame class, which contains the image and the topleft_label, "Welcome - Login Screen". This means the StartPage object can inherit the background image from the base_frame class.
The Code
import tkinter as tk
LARGE_FONT= ("Verdana", 12)
HEIGHT = 768
WIDTH = 1366
class MainApp():
def __init__(self, master):
self.master = master
self.master.title("Sales System")
self.master.geometry("%dx%d+0+0" % (WIDTH, HEIGHT))
self.frames = {}
start_page = StartPage(master)
self.frames[StartPage] = start_page
start_page.grid(row=0, column=0, sticky="nsew")
self.master.grid_rowconfigure(0, weight=1)
self.master.grid_columnconfigure(0, weight=1)
self.show_frame(StartPage)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class base_frame(tk.Frame):
def __init__(self, master, *args, **kwargs):
tk.Frame.__init__(master, *args, **kwargs)
b_image = tk.PhotoImage(file='background.png')
b_label = tk.Label(self, image=b_image)
b_label.image = b_image
b_label.place(x=0, y=0, relwidth=1, relheight=1)
topleft_label = tk.Label(self, bg='black', fg='white', text="Welcome - Login Screen", justify='left', anchor="w", font="Verdana 12")
topleft_label.place(relwidth=0.5, relheight=0.05, relx=0.25, rely=0, anchor='n')
class StartPage(base_frame):
def __init__(self, parent):
super().__init__(self, parent)
label = tk.Label(self, text="Start Page", font=LARGE_FONT)
label.pack(pady=10,padx=10)
def main():
root = tk.Tk() # MainApp()
main_app = MainApp(root)
root.mainloop()
if __name__ == '__main__':
main()
The Breakdown
Starting the Code
The piece of code that makes this class system run is like so:
def main():
root = tk.Tk() # MainApp()
main_app = MainApp(root)
root.mainloop()
if __name__ == '__main__':
main()
The line if __name__ == '__main__':, in English, roughly translates too: If the program is run and not imported. So, if the program is run and not imported, run the main function.
root = tk.Tk() simply creates a Tk window inside of the root variable.
main_app = MainApp(root) initializes the main_app object with its master being the root variable
root.mainloop() starts the tkinter loop.
The MainApp Class
The MainApp Class starts by setting its title to "Sales System" and resetting the geometry to the values defined in HEIGHT & WIDTH:
self.master = master
self.master.title("Sales System")
self.master.geometry("%dx%d+0+0" % (WIDTH, HEIGHT))
Then the self.frames dictionary & the start_page is initialized and the start_page is placed in self.frames:
self.frames = {}
start_page = StartPage(master)
self.frames[StartPage] = start_page
The start_page is then set to fill the whole of the window:
start_page.grid(row=0, column=0, sticky="nsew")
self.master.grid_rowconfigure(0, weight=1)
self.master.grid_columnconfigure(0, weight=1)
We then show the first page:
self.show_frame(StartPage)
The show_frame function is then created
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
The base_frame Class
The first 3 lines creates a class which takes values the same as a tk.Frame object does, with args and key word args passed through:
class base_frame(tk.Frame):
def __init__(self, master, *args, **kwargs):
tk.Frame.__init__(master, *args, **kwargs)
Then the image label is created:
b_image = tk.PhotoImage(file='background.png')
b_label = tk.Label(self, image=b_image)
b_label.image = b_image
b_label.place(x=0, y=0, relwidth=1, relheight=1)
The b_label.image = b_image line is used to make sure the image is shown by the label (this is required when loading from within a function).
We then create the default topleft_label:
topleft_label = tk.Label(self, bg='black', fg='white', text="Welcome - Login Screen", justify='left', anchor="w", font="Verdana 12")
topleft_label.place(relwidth=0.5, relheight=0.05, relx=0.25, rely=0, anchor='n')
You may wish to update this code for these labels to be changed in the future, to do this simply replace topleft_label with self.topleft_label and b_label with self.b_label
The StartPage Class
This class is not much different to the class you created previously:
class StartPage(base_frame):
def __init__(self, parent):
super().__init__(self, parent)
label = tk.Label(self, text="Start Page", font=LARGE_FONT)
label.pack(pady=10,padx=10)
The only difference being instead of inheriting from tk.Frame, it inherits from the base_frame class.

the tkinter widgets in my classes are not displaying

I'm trying to write a code that contains multiple pages and can be switched to when a button is clicked on. it worked initially but my widgets are not displaying, and there is neither a warning or an error message. Secondly, what is the difference between using tk and tk.TK?
from tkinter import *
import tkinter as tk
class moreTab(tk.Tk):
def __init__(self):
Tk.__init__(self)
self.geometry("1200x600")
container = Frame(self, bg='#c9e3c1')
container.pack(side = "top", fill = 'both', expand = True)
container.grid_rowconfigure(0, weight = 1)
container.grid_columnconfigure(0, weight = 1)
self.frames = {}
for q in (pageone, widget):
frame = q(container,self)
self.frames[q] = frame
frame.place(x= 0,y = 0)
self.raise_frame(pageone)
def raise_frame(self,cont):
frame = self.frames[cont]
frame.tkraise()
class widget(Frame):
def __init__(self, master, control):
Frame.__init__(self, master)
lab = tk.Label(self, text="main page")
lab.place(x = 10, y = 40)
but = tk.Button(self, text='visit start page', command=lambda:
control.raise_frame(pageone))
but.place(x = 10, y = 70)
class pageone(Frame):
def __init__(self, master, control):
Frame.__init__(self,master)
lab = Label(self, text = 'welcome to Game Analysis')
lab.place(x = 10, y = 10)
but = Button(self, text = "Start", command = lambda:
control.raise_frame(widget))
but.place(x = 10, y = 20)
app = moreTab()
app.mainloop()
It turns the issue was that you were using place(). Use the grid geometry manager. Using both import tkinter as tk and from tkinter import * is meaningless. Use one and be consistent. If you use the latter, you have everything available, hence you will write, say Button(...). But if you use the former, you will have to refer each widget like tk.Button(...).
import tkinter as tk
class moreTab(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.geometry("1200x600")
container = tk.Frame(self, bg='#c9e3c1')
container.pack(side = "top", fill = 'both', expand = True)
container.grid_rowconfigure(0, weight = 1)
container.grid_columnconfigure(0, weight = 1)
self.frames = {}
for q in (pageone, widget):
frame = q(container, self)
self.frames[q] = frame
frame.grid(row=0, column=0, sticky='nsew')
self.raise_frame(pageone)
def raise_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class widget(tk.Frame):
def __init__(self, master, control):
tk.Frame.__init__(self, master)
lab = tk.Label(self, text="main page")
lab.grid(row=0, column=0, padx=10, pady=10)
but = tk.Button(self, text='visit start page', command=lambda: control.raise_frame(pageone))
but.grid(row=1, column=0, padx=10, pady=10)
class pageone(tk.Frame):
def __init__(self, master, control):
tk.Frame.__init__(self, master)
lab = tk.Label(self, text = 'welcome to Game Analysis')
lab.grid(row=0, column=0, padx=10, pady=10)
but = tk.Button(self, text = "Start", command = lambda: control.raise_frame(widget))
but.grid(row=1, column=0, padx=10, pady=10)
app = moreTab()
app.mainloop()

Categories

Resources