Python, Tkinter OptionMenu widget & making use of it - python

I'm trying to create a number of frames to be accessed through the use of the menu widget. When using the menu, you can click on one of the commands - it would bring up a frame and the menu widget should still be at the top, so you can easily decide where to go.
I'm trying to make use of the option menu widget within a function which is called after a login page, therefore I'm using the top level method within it. When attempting to do this option menu I encountered a few problems and I'm currently stuck as well as not understanding what's wrong with the code, so I was hoping someone would tell me what's wrong with it.
CoreContent = function named
myGUI = main root
def CoreContent():
#Building core content/structure
myGUI.withdraw() # This is the main root that I remove after user logs in
CoreRoot = Toplevel(myGUI, bg="powderblue") # Toplevel
CoreRoot.title("titletest")
CoreRoot.geometry('300x500')
CoreRoot.resizable(width=False, height=False)
#Creating drop-down menu
menu = Menu(CoreRoot)
CoreRoot.config(menu=menu)
filemenu = Menu(menu)
menu.add_cascade(label="File", menu=filemenu)
filemenu.add_command(label="test one", command=lambda: doNothing()) # Problem
filemenu.add_command(label="soon")
filemenu.add_separator()
filemenu.add_command(label="Exit")
I'm confused how and where I should create the frames to add as a command to make use of within the option menu widget.

For a clear description of how to switch between frames in Tkinter, check this link: Switch between two frames in tkinter
To do it from a menu, you could write something like this:
import tkinter as tk
# method to raise a frame to the top
def raise_frame(frame):
frame.tkraise()
# Create a root, and add a menu
root = tk.Tk()
menu = tk.Menu(root)
root.config(menu=menu)
filemenu = tk.Menu(menu)
menu.add_cascade(label="File", menu=filemenu)
filemenu.add_command(label="test one", command=lambda: raise_frame(f1))
filemenu.add_command(label="test two", command=lambda: raise_frame(f2))
# Create two frames on top of each other
f1 = tk.Frame(root)
f2 = tk.Frame(root)
for frame in (f1, f2):
frame.grid(row=0, column=0, sticky='news')
# Add widgets to the frames
tk.Label(f1, text='FRAME 1').pack()
tk.Label(f2, text='FRAME 2').pack()
# Launch the app
root.mainloop()

Related

Trying to make a tkinter menu button that do multiple tasks

I've been trying to make a button in menu bar in the tkinter app and can't seem to figure out how to make this button make multiple tasks. I've tried the following, it forgets the frame correctly but don't execute the carr function.
from tkinter import *
root = Tk()
menu_bar = Menu(root)
file_menu = Menu(menu_bar, tearoff = 0)
file_menu.add_command(label="Carré", command=lambda:[frame.pack_forget(),carr])
menu_bar.add_cascade(label="Séléction", menu=file_menu)
root.config(menu=menu_bar)
root.mainloop()
The proper solution is to create a function for the button.
def do_carr():
frame.pack_forget()
carr()
...
file_menu.add_command(label="Carré", command=do_carr)

Tkinter toplevel window is not defined

I wonder if someone could tell me if its possible to update toplevel windows using external functions. I've replicated my issue below what I need to do is update the Toplevel(master) using the function updatelabel(). I have used similar external function to update items in root which works like a dream. However, with the top level window I always get the
NameError: name 'newWindow' is not defined
The only work around I found was to kill the newWindow using newWindow.destroy() on each load but this method makes the screen pop up and then close again which doesn't look pretty. Any help most welcome thanks.
from tkinter import *
from tkinter.ttk import *
master = Tk()
master.geometry("200x200")
def updatelabel():
Label(newWindow,
text="I changed").pack()
def openNewWindow():
# Toplevel object which will
# be treated as a new window
newWindow = Toplevel(master)
# sets the title of the
# Toplevel widget
newWindow.title("New Window")
# sets the geometry of toplevel
newWindow.geometry("200x200")
# A Label widget to show in toplevel
Label(newWindow,
text="I want to change").pack()
button1 = Button(newWindow,
text="Click me to change label", command=updatelabel).pack()
btn = Button(master,
text="open a new window",
command=openNewWindow)
btn.pack(pady=10)
mainloop()
Your “newWindow” is defined in your “openNewWindow” function and so it basically only exists in there, you could probably fix this by either defining “newWindow” outside of the function, or by using it as an argument(just add it to the brackets and give it a name in the function itself’s brackets) calling “updateLabel”
I think this should work, though I haven’t worked with tkinter in a bit so don’t blame me if it doesn’t
from tkinter import *
from tkinter.ttk import *
master = Tk()
master.geometry("200x200")
def updatelabel(newWindow):
Label(newWindow,
text="I changed").pack()
def openNewWindow():
# Toplevel object which will
# be treated as a new window
newWindow = Toplevel(master)
# sets the title of the
# Toplevel widget
newWindow.title("New Window")
# sets the geometry of toplevel
newWindow.geometry("200x200")
# A Label widget to show in toplevel
Label(newWindow,
text="I want to change").pack()
button1 = Button(newWindow,
text="Click me to change label", command= lambda: updatelabel(newWindow)).pack()
btn = Button(master,
text="open a new window",
command=openNewWindow)
btn.pack(pady=10)
mainloop()

Opening a new window using a link in tkinter

How do I open a new window using a link in tkinter .
(For eg : in a login window i want to add a link that says "New user ? click here" and when I click on "click here" it takes me to the register window .
Please help me
enter image description here
[1]: https://i.stack.imgur.com/K5GV0.png
Please click the above link to see the image
Creating new toplevel windows works almost exactly the same as creating new widgets.
Toplevel windows are created using the Toplevel function:
t = Toplevel(parent)
Unlike regular widgets, you don't have to "Grid" a toplevel fo it to appear on screen. Once you've created a toplevel you can add children widgets within and grid them like in the main window. In other words toplevel behaves exactly like the automatic created root window.
To destroy a window use the method:
window.destroy()
You can open new windows in tkinter with the tkinter.Toplevel() command.
import tkinter as tk
class Gui:
"""Gui class"""
def __init__(self):
self.root = tk.Tk()
self.new_window = tk.Button(master=self.root, text="Open new window", width=20, pady=4, command=self.new_window)
self.new_window.pack()
self.root.mainloop()
def new_window(self):
"""Create a new top level window"""
new_window = tk.Toplevel()
tk.Label(master=new_window, text="This is a new window").pack()
if __name__ == '__main__':
Gui()
You can create a function to open a new window and then bind it to that Label, for example:
import tkinter as tk
def newWindow():
# Window object (top level)
newWindow = Toplevel(master)
# Title
newWindow.title("New Window 1")
# Geometry
newWindow.geometry("300x300")
root = tk.Tk()
label = tk.Label(text="Hello!", width=50, height=10, master=root)
label.pack()
label.bind("<Button-1>", newWindow)

Tkinter menu is not appearing on MacOS 11.2.2

I am trying to create an application to show real-time data in a study on electrical systems. The menu will be used to open information on history of each of the graphs shown on the "front page" and will also include a quit option. When I create the menu and add a couple items to it, it does not show up when I run the application. Unfortunately in my searches, all the alternatives I have tried do not show up either.
from tkinter import *
from tkinter import ttk
class PicoGridInterfacing(Frame):
def __init__(self, master=None):
super().__init__(master)
self.master = master
self.grid()
menubar = Menu(root)
menu = Menu(menubar)
menubar.add_cascade(label="Menu", menu=menu)
menu.add_command(label="History", command=None)
menu.add_command(label="Quit", command=root.quit)
batteryData = Frame(root)
batteryData.grid(row=1, column=0)
Label(batteryData, text="Hello!").grid()
root = Tk()
root.title("Electric Power Systems Lab Pico Grid Interfacing")
app = PicoGridInterfacing(master=root)
root.mainloop()
Here's a screenshot of the output I see:
Screenshot of output
Any help would be greatly appreciated, thank you!
Try this:
from tkinter import *
from tkinter import ttk
class PicoGridInterfacing(Frame):
def __init__(self, master=None):
super().__init__(master)
# master = master # `super().__init__(master)` already does that so its useless
# Creating the menu
menubar = Menu(root)
menu = Menu(menubar, tearoff=False)
menubar.add_cascade(label="Menu", menu=menu)
menu.add_command(label="History", command=None)
menu.add_command(label="Quit", command=root.destroy)
# Tell the `Tk()` that there is a menu that it need to display:
master.config(menu=menubar)
batteryData = Frame(self)
batteryData.grid(row=1, column=0)
Label(batteryData, text="Hello!").grid()
root = Tk()
root.title("Electric Power Systems Lab Pico Grid Interfacing")
app = PicoGridInterfacing(master=root)
# When you inherit from `Frame` you always what the user to call `.grid`
app.grid()
root.mainloop()
You need to tell the tkinter.Tk() that there is a menu otherwise it will ignore it. Also when inheriting from tkinter.Frame it's the caller's job to call .grid (it's convention).
You need to attach the menu bar to the root window.
So do this: root.config(menu=menubar)

Placing Tkinter Frame in another Frame

I am trying to experiment and get the button to only display the label when the button is clicked instead it is opening up another GUI window. The main frame is called secret message. Within this when i click onto the button it should then replace the empty place with the label in row=2.
Could someone explain to me how i can raise the label rather than just opening up a new window. All code is functional but i want another way around this, i am new to python.
from tkinter import *
def topLevel():
top=Toplevel()
top.geometry("300x200")
root=Tk()
root.title("Secret Message")
button1 = Button(text="Push this button to see hidden message!", width =60, command=topLevel)
button1.grid(row=1, column=0)
label1 = Label(width=50, height=10, background="WHITE", text= "There is no secret!")
label1.grid(row=2, column=0)
root.mainloop()
You question title has nothing to do with your question.
To update the geometry of your label you simple need to tell the function where you want the label on the container you set up your label in. In this case you do not define the container so the widgets default to the root window.
Here is a working example that will update the label geometry when you press the button.
from tkinter import *
root=Tk()
root.title("Secret Message")
def grid_label():
label1.config(text="There is no secret!")
Button(root, text="Push this button to see hidden message!", width=60, command=grid_label).grid(row=1, column=0)
label1 = Label(root, width=50, height=10, background="WHITE")
label1.grid(row=2, column=0)
root.mainloop()

Categories

Resources