I'm trying to make a calculator and it has different frames i.e Basic, Statistics, ..., etc. However, I'm having issues to show each frame.
This is the container for all the frames (I took a code of a previous post as example)
import tkinter as tk
class calculatorframe(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
#----------------CONTAINER FOR ALL THE FRAMES----------
container = tk.Frame(self)
container.pack()
#--------------------- DROPDOWN MENU------------------
tkvar = tk.StringVar()
choices={'Basic Mode','Calculus Mode'} #Options of the dropdown menu
tkvar.set('Basic Mode') #default frame
dropdownmenu =tk.OptionMenu(container, tkvar, *choices)
dropdownmenu.grid(row=2,column=3) #position of the dropdown menu
self.frames = {}
for F in (Basic, Calculus):
page_name = F.__name__
frame = F(parent= container, controller=self)
self.frames[page_name] = frame
frame.grid(row=0, column=0, sticky= "nsew")
self.show_frame('Basic')
#-------FUNCTION TO SHOW THE CURRENT FRAME
def show_frame(self, page_name):
frame = self.frames[page_name]
frame.tkraise()
These are the classes that I created for the basic calculator
class Basic(tk.Frame):
def __init__(self, parent, controller):
#--------------- SCREEN ---------------
tk.Frame.__init__(self, parent)
screen = tk.Entry(self, width=80)
screen.grid(row=3, column=1,columnspan=7) #position of the screen
#------------ BUTTON ---------------------
button7=tk.Button(self, text="7", width=8) #button
button7.grid(row=4,column=1)
#---------------------frame for calculus -------------------------
class Calculus(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
#-----------------------------SCREEN------------
screen=tk.Entry(self, width=50)
screen.pack()
screen.grid(row=3, column=1, pady=20, columnspan=7) #position of the screen
#------------------------BUTTON---------------
go=tk.Button(self, height=1, text="Go") #button
go.grid(row=1, column=8)
if __name__ == "__main__":
app = calculatorframe()
app.mainloop()
I'm aware that I have to keep track of the value of tkvar and that I need to do it using trace() and pass that value to show_frame, however, I don't know where to place it in my code. I tried to put it below the dropdown menu, but I get an error message and I tried after the function show_frame and it did not work either. I'm a bit stuck, I would really appreciate your help, thanks in advance.
The simple solution would be to add a command to your OptionsMenu() function. We will also need to change your class names and your choice options due to how the command argument works here.
For the OptionsMenu() command argument when you tell it to call a method it will automatically pass the value of the selected item in the drop down. So because of this we need to make sure our selection reflect the class names. You can change the choices/classes to be whatever you wish I just used BasicMode and CalculusMode as an example.
The command will automatically pass the value selected so we can use that to call each frame using you show_frame method.
Take a look at the below code and let me know if you have any questions.
import tkinter as tk
class calculatorframe(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
container = tk.Frame(self)
container.pack()
tkvar = tk.StringVar()
choices = {'BasicMode', 'CalculusMode'}
tkvar.set('BasicMode')
dropdownmenu = tk.OptionMenu(container, tkvar, *choices, command=self.show_frame)
dropdownmenu.grid(row=2, column=3)
self.frames = {}
for F in (BasicMode, CalculusMode):
page_name = F.__name__
frame = F(parent= container, controller=self)
self.frames[page_name] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame('BasicMode')
def show_frame(self, page_name):
frame = self.frames[page_name]
frame.tkraise()
class BasicMode(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
screen = tk.Entry(self, width=80)
screen.grid(row=3, column=1, columnspan=7)
button7 = tk.Button(self, text="7", width=8)
button7.grid(row=4,column=1)
class CalculusMode(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
screen = tk.Entry(self, width=50)
screen.pack()
screen.grid(row=3, column=1, pady=20, columnspan=7)
go = tk.Button(self, height=1, text="Go")
go.grid(row=1, column=8)
if __name__ == "__main__":
app = calculatorframe()
app.mainloop()
Related
I'm new to Tkinter and python. I'm following Switch between two frames in tkinter to see switch frames and it worked. Next, I'm trying to write the code for switch frames inside Page One, but I don't have any idea how to do it.
Below is the code:
from tkinter import *
import tkinter as tk
from tkinter import font as tkfont
class SampleApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.title_font = tkfont.Font(family='Helvetica', size=18, weight="bold", slant="italic")
# the container is where we'll stack a bunch of frames
# on top of each other, then the one we want visible
# will be raised above the others
container = tk.Frame(self)
container.pack(side="top", fill="both", expand=True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
width = 1350 # 1280
height = 720
screen_width = self.winfo_screenwidth()
screen_height = self.winfo_screenheight()
x = (screen_width / 2) - (width / 2)
y = (screen_height / 2) - (height / 2)
self.geometry(f'{width}x{height}+{int(x)}+{int(y)}')
self.resizable(False,False)
self.frames = {}
for F in (StartPage, PageOne):
page_name = F.__name__
frame = F(parent=container, controller=self)
self.frames[page_name] = frame
# put all of the pages in the same location;
# the one on the top of the stacking order
# will be the one that is visible.
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame("StartPage")
def show_frame(self, page_name):
'''Show a frame for the given page name'''
frame = self.frames[page_name]
frame.tkraise()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="This is the start page", font=controller.title_font)
label.pack(side="top", fill="x", pady=10)
button1 = tk.Button(self, text="Go to Page One",command=lambda: controller.show_frame("PageOne"))
button1.pack()
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
LeftFrame=tk.Frame(self,relief=RIDGE, bd=2)
LeftFrame.place(x=0,y=0,width=160,height=720)
button = tk.Button(LeftFrame, text="Go to the start page",font=("bold"),command=lambda: controller.show_frame("StartPage"))
button.grid(row=0)
buttonBlue = tk.Button(LeftFrame, text="Go to the blue page",bg="blue",fg="white",command=self.blue,activebackground="blue",activeforeground="white")
buttonBlue.grid(row=1)
buttonRed = tk.Button(LeftFrame, text="Go to the red page",bg="red",fg="white",command=self.red,activebackground="red",activeforeground="white")
buttonRed.grid(row=2)
buttonYellow = tk.Button(LeftFrame, text="Go to the yellow page",bg="yellow",fg="black",command=self.yellow,activebackground="yellow",activeforeground="black")
buttonYellow.grid(row=3)
def blue(self):
# self.hide_all_frames()
blueFrame=tk.Frame(self,relief=RIDGE,bd=1 ,bg="blue")
blueFrame.place(x=160,y=0,width=1190,height=720)
def red(self): # Do I need to put self here? It still worked without putting self here
# self.hide_all_frames()
redFrame=tk.Frame(self,relief=RIDGE,bd=1 ,bg="red")
redFrame.place(x=200,y=0,width=1150,height=720)
def yellow(self):
# self.hide_all_frames()
yellowFrame=tk.Frame(self,relief=RIDGE,bd=1 ,bg="yellow")
yellowFrame.place(x=240,y=0,width=1110,height=720)
def hide_all_frames(self):
self.blue.withdraw()
if __name__ == "__main__":
app = SampleApp()
app.mainloop()
When I switch to Page One, I create a couple of buttons to switch color frames. They all overlap every time I switch between colors like the image below.
I'm finding a way to switch color frames without overlapping each other. And, when I go back to the Start Page, all color frames should be destroyed/hidden. Please help me. Thank you so much.
For the frame switching inside PageOne, you need to hide the current frame before showing the requested frame. Also it is better to create the three color frames in the __init__() and show it in the corresponding function:
class PageOne(tk.Frame):
def __init__(self, parent, controller):
...
# create the three color frames with initially hidden
self.blueFrame = tk.Frame(self, relief=RIDGE, bd=1, bg="blue")
self.redFrame = tk.Frame(self, relief=RIDGE, bd=1, bg="red")
self.yellowFrame = tk.Frame(self, relief=RIDGE, bd=1, bg="yellow")
def blue(self):
self.hide_all_frames()
self.blueFrame.place(x=160, y=0, width=1190, height=720)
def red(self):
self.hide_all_frames()
self.redFrame.place(x=200, y=0, width=1150, height=720)
def yellow(self):
self.hide_all_frames()
self.yellowFrame.place(x=240, y=0, width=1110, height=720)
def hide_all_frames(self, event=None):
self.redFrame.place_forget()
self.blueFrame.place_forget()
self.yellowFrame.place_forget()
If you want to hide all color frames after switching frames, i.e. PageOne -> MainPage -> PageOne, you can notify the PageOne using virtual event when it is raised. Then PageOne hides all the color frames upon receiving such virtual event:
class SampleApp(tk.Tk):
...
def show_frame(self, page_name):
'''Show a frame for the given page name'''
frame = self.frames[page_name]
frame.tkraise()
# notify the raised frame via virtual event
frame.event_generate('<<Raised>>')
...
class PageOne(tk.Frame):
def __init__(self, parent, controller):
...
self.blueFrame = tk.Frame(self, relief=RIDGE, bd=1, bg="blue")
self.redFrame = tk.Frame(self, relief=RIDGE, bd=1, bg="red")
self.yellowFrame = tk.Frame(self, relief=RIDGE, bd=1, bg="yellow")
self.bind('<<Raised>>', self.hide_all_frames)
I am trying to use GPS sensor with RPI and make its GUI using Tkinter. I want to update my GPS value and shows in the GUI. But in GUI it shows only initial value. In backend GPS value is updating but unable to show in GUI.
import tkinter as tk
import serial
import time
import webbrowser as wb
ser = serial.Serial('/dev/ttyUSB0', 9600)
class IotCar(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
width=tk.Tk.winfo_screenwidth(self)
height=tk.Tk.winfo_screenheight(self)
tk.Tk.geometry(self, '{}x{}'.format(width, height))
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 each_frame in (StartPage, HomePage):
frame = each_frame(container, self)
self.frames[each_frame]=frame
frame.grid(row=0, column=0, sticky='nsew')
self.show_page(StartPage)
def show_page(self, cont):
frame=self.frames[cont]
frame.tkraise()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
next_button = tk.Button(self, text='Next', command=lambda:
controller.show_page(HomePage)).pack(side=tk.TOP,padx=5, pady=5)
class HomePage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.gps_pos()
self.lat1 = tk.StringVar()
self.lon1=tk.StringVar(self)
self.label_lat = tk.Label(self.HomePage, text='Latitude', justify=tk.LEFT, padx=10).pack()
self.label_lat1 = tk.Label(self.HomePage, textvariable=self.lat1, justify=tk.LEFT,
borderwidth=2, relief='ridge').pack()
self.label_lon = tk.Label(self, text='Longitude', justify=tk.LEFT, padx=10).pack()
self.label_lon1 = tk.Label(self, text=self.lon1, justify=tk.LEFT,
borderwidth=2, relief='ridge').pack()
def gps_pos(self):
print('Entered into gps')
ser.flushInput()
ser.flushOutput()
ser.write(b'AT+CGPSPWR=1\r')
ser.write(b'AT+CGPSOUT=32\r')
while True:
gps=str(ser.readline())
gps=gps[2:].split(',')
if gps[0]=='$GPRMC' and gps[3]!='':
lat=gps[1]
lon=gps[1]
break;
self.after(3000,self.gps_pos)
print(lat, lon)
self.lat1.set(lat1)
app = IotCar()
app.mainloop()
Please help me to understand what is wrong in it. Thank you in advance.
I am unable to run this script as I don't have the serial module however I have modified a few things and this populates the label with text (comments in code). You need a function that will assign the "text" parameters in the labels with a value.
import tkinter as tk
import time
import webbrowser as wb
class IotCar(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
width=tk.Tk.winfo_screenwidth(self)
height=tk.Tk.winfo_screenheight(self)
tk.Tk.geometry(self, '{}x{}'.format(width, height))
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 each_frame in (StartPage, HomePage):
frame = each_frame(container, self)
self.frames[each_frame]=frame
frame.grid(row=0, column=0, sticky='nsew')
self.show_page(StartPage)
def show_page(self, cont):
frame=self.frames[cont]
frame.tkraise()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
next_button = tk.Button(self, text='Next', command=lambda:
controller.show_page(HomePage)).pack(side=tk.TOP,padx=5, pady=5)
class HomePage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.lat1 = tk.StringVar()
self.lon1 = tk.StringVar(self)
self.label_lat = tk.Label(self, text='Latitude', justify=tk.LEFT, padx=10)
self.label_lat.pack()
self.label_lat1 = tk.Label(self, justify=tk.LEFT,
borderwidth=2, relief='ridge') # I have removed the "text" parameter because my function will update it.
self.label_lat1.pack()
self.label_lon = tk.Label(self, text='Longitude', justify=tk.LEFT, padx=10)
self.label_lon.pack()
self.label_lon1 = tk.Label(self, justify=tk.LEFT,
borderwidth=2, relief='ridge') # I have removed the "text" parameter because my function will update it.
self.label_lon1.pack()
button = tk.Button(self, text="update label", bg= "#aaaaaa", fg ="#483F44",
font=("Arial", 10, "bold"), relief="groove", command = lambda: helloworld()) # This button will run the helloworld function
button.pack()
def helloworld():
self.label_lat1["text"] = "Hello" #This will update the text parameter in label_lat1 with "Hello"
self.label_lon1["text"] = "World" #This will update the text parameter in label_lon1 with "World"
app = IotCar()
app.mainloop()
A few things to note is to pack/place/grid your labels separately from when you define its parameters i believe that the way you have currently set up the widget is giving it a None type which is why you can't assign text to it:
#You write
self.label_lat1 = tk.Label(self.HomePage, textvariable=self.lat1, justify=tk.LEFT,
borderwidth=2, relief='ridge').pack()
#My example
self.label_lat1 = tk.Label(self, justify=tk.LEFT,
borderwidth=2, relief='ridge')
self.label_lat1.pack()
You then need a command that will run a function and in that function will have a variable which will assign a text value to the label (i.e. the helloworld function in my code).
Looking at your code i believe you will need to amend the way you are packing your widgets and then in your function do something like
def gps_pos(self):
print(lat, lon)
self.label_lat1["text"] = lat
self.label_lon1["text"] = lon
Below is a very useful answer on how to layout your tkinter gui and various other FAQ. I myself found it extremely useful
Switch between two frames in tkinter
I'm currently working on a GUI using tkinter which allows the user to navigate between different frames. I based my code structure on this user response.
My issue now is to automatically adjust tkinter's window to its contents when a frame is changed. I want the borders of the window to fit the widgets following the red arrows as in here and here (the outputs from the sample code below), so that there is no such "empty space" in each frame.
The code works in a way that the method show_frame allows the change between the two defined frames.
from tkinter import *
class WindowController(Tk):
def __init__(self, *args, **kwargs):
Tk.__init__(self, *args, **kwargs)
container = Frame(root)
container.grid()
self.frames = {}
for F in (FirstWindow, SecondWindow):
frame = F(parent=container, controller=self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(FirstWindow)
self.destroy()
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class FirstWindow(Frame):
def __init__(self, parent, controller):
self.controller = controller
self.parent = parent
Frame.__init__(self, parent)
# Widgets:
# "Do Nothing" Button
self.Title0 = Button(self, text='Do nothing')
self.Title0.grid(row=0, column=0)
# "Do Nothing" Button
self.Title1 = Button(self, text='Do Nothing')
self.Title1.grid(row=1, column=0)
# Change Frame Button
self.Title2 = Button(self, text='To Second Window', command=lambda: self.controller.show_frame(SecondWindow))
self.Title2.grid(row=2, column=0)
class SecondWindow(Frame):
def __init__(self, parent, controller):
self.controller = controller
self.parent = parent
Frame.__init__(self, parent)
# Widgets:
# "Do Nothing" Button
self.Title0 = Button(self, text='Do nothing')
self.Title0.grid(row=0, column=0)
# "Do Nothing" Button
self.Title1 = Button(self, text='Do Nothing')
self.Title1.grid(row=0, column=1)
# Change Frame Button
self.Title2 = Button(self, text='To First Window', command=lambda: self.controller.show_frame(FirstWindow))
self.Title2.grid(row=0, column=2)
if __name__ == "__main__":
root = Tk()
root.resizable(width=False, height=False)
app = WindowController()
app.mainloop()
My problem seems to be similar to the one in here, but it wasn't solved.
This is my first question here, so criticism is very much appreciated.
The answer is in the question Tkinter Frame Resize: Since both frames are gridded the window will expand to contain them both.
To get the window to change size you need to have only one frame gridded at a time.
To remove a frame from a window and still remember its attributes use:
frame.grid_remove()
To display the frame again use:
frame.grid() # Will remember grid settings
This code works but you could probably improve on its beauty:
class WindowController(Tk):
def __init__(self, *args, **kwargs):
Tk.__init__(self, *args, **kwargs)
container = Frame(root)
container.grid()
self.frames = {}
for F in (FirstWindow, SecondWindow):
frame = F(parent=container, controller=self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
frame.grid_remove() # Remove all frames
self.show_frame(FirstWindow)
self.destroy()
def show_frame(self, cont):
for fme in self.frames: # Remove all frames
self.frames[fme].grid_remove()
frame = self.frames[cont]
frame.grid() # Display frame
I managed to build a little GUI, where I can switch between frames related to the following question: Switch between frames in tkinter
I wanted to have a status bar on the Bottom of my GUI and it should stay on every frame! The status bar shows info about buttons when hovering over it!
Not hovered:
Hovered:
As you can see it works, BUT I can't manage to make the status bar update its values when another frame is raised, because I could only manage to create the status bar in one frame class...
class SampleApp(Tk):
def __init__(self, *args, **kwargs):
Tk.__init__(self, *args, **kwargs)
self.title_font = font.Font(family='Helvetica', size=18,
weight="bold", slant="italic")
container = 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 (start_frame, cr_frame, db_frame):
page_name = F.__name__
frame = F(parent=container, controller=self)
self.frames[page_name] = frame
frame.pack()
self.show_frame("start_frame")
def show_frame(self, page_name):
'''Show a frame for the given page name'''
for frame in self.frames.values():
#frame.grid_remove()
frame.pack_forget()
frame = self.frames[page_name]
frame.pack()
if page_name == "start_frame":
frame.winfo_toplevel().geometry("545x200")
if page_name == "cr_frame":
frame.winfo_toplevel().geometry("600x200")
if page_name == "db_frame":
frame.winfo_toplevel().geometry("700x630")
class start_frame(Frame):
def __init__(self, parent, controller):
Frame.__init__(self, parent)
self.controller = controller
self.btn_cr = Button(self, text="Copyright Analyse", command=lambda: self.controller.show_frame("cr_frame"), width=40)
self.btn_cr.pack(side=LEFT, padx=15, pady=1, ipady=40)
self.btn_db = Button(self, text="Copyright Datenbank", command=lambda: self.controller.show_frame("db_frame"), width=40)
self.btn_db.pack(side=LEFT, pady=1, ipady=40)
###################Here is the statusbar defined + bindings and so on##########
self.lbl_status = Label(self.controller, text="...", border=1, relief=SUNKEN, anchor=W)
self.lbl_status.pack(side=BOTTOM, fill=X, anchor=W)
self.btn_cr.bind("<Enter>", lambda event: self.lbl_status.configure(text="Open copyright analysis window..."))
self.btn_cr.bind("<Leave>", self.leave_bindings)
self.btn_db.bind("<Enter>", lambda event: self.lbl_status.configure(text="Open copyright database..."))
self.btn_db.bind("<Leave>", self.leave_bindings)
class cr_frame(Frame):
def __init__(self, parent, controller):
Frame.__init__(self, parent)
self.controller = controller
Now, if I switch to page 2 (cr_frame), the status bar is still there because I attached it to the top-level controller (of all frames) but I can't edit it through the cr_frame class...
I don't know how to do it.
First, move the statusbar to the main app since it's part of the app and not part of a page:
class SampleApp(Tk):
def __init__(self, *args, **kwargs):
...
container = Frame(self)
self.lbl_status = Label(self, text="", border=1, relief=SUNKEN, anchor=W)
container.pack(side="top", fill="both", expand=True)
self.lbl_status.pack(side="bottom", fill="x")
Next, add a method to the app for setting the status:
class SampleApp(Tk):
...
def set_status(self, string):
self.lbl_status.configure(text=string)
Finally, call that method whenever you need to change the status:
class cr_frame(Frame):
def __init__(self, parent, controller):
Frame.__init__(self, parent)
self.controller = controller
...
def something(self):
...
self.controller.set_status("Hello, world")
...
I have a superclass (tk window) , and another subclass (tk window) which inherits properties from the original class. on the super class, I have a method callback which is called every second. The subclass displays a tk options menu, and i would like to update the options displayed in the tk options menu though the superclass method which is called every second. I've created a shortened version of my program which shows generally what I'm trying to do. This program will run, and it works as i'd like it to, but in pycharm I receive a warning highlighting the subclass method def update(self, controller)::
Signature of method 'OtherPage.update()' does not match
signature of base method in class 'Misc'
what is the correct way to do this?
import tkinter as tk
exchanges = ['Bitfinex', 'Bittrex', 'Kraken', 'Gdax']
class Trader(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
tk.Tk.wm_title(self, "Multi-Trader-Wallet")
container = tk.Frame(self)
container.pack(side="top", fill="both", expand=True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
menubar = tk.Menu(container)
filemenu = tk.Menu(menubar, tearoff=0)
filemenu.add_command(label='Exit', command=lambda: print('exit'))
menubar.add_cascade(label='File', menu=filemenu)
tk.Tk.config(self, menu=menubar)
self.exchange1 = tk.StringVar()
self.frames = {}
self.id = self.after(1000, self.callback)
for F in (MainPage, OtherPage):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, columnspan=1, rowspan=1, sticky="nsew")
self.show_frame(OtherPage)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
def callback(self):
print('callback')
print(self.frames[OtherPage])
self.frames[OtherPage].update(self)
self.id = self.after(1000, self.callback)
class MainPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text='MainPage')
label.grid(row=1, column=1)
class OtherPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label2 = tk.Label(self, text='OtherPage')
label2.grid(row=1, column=1)
drop = tk.OptionMenu(self, controller.exchange1, *exchanges)
drop.config(width=10)
drop.grid(row=2, column=1)
def update(self, controller):
exchanges.append('new exchange')
drop = tk.OptionMenu(self, controller.exchange1, *exchanges)
drop.config(width=10)
drop.grid(row=2, column=1)
app = Trader()
app.mainloop()