Tkinter menu is not appearing on MacOS 11.2.2 - python

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)

Related

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)

Toplevel from a Toplevel behavior on Tkinter Python

So I made this simple code to recreate the way I want my actual app to behave (sorry, if I didn't use oop and really new into this):
import tkinter as tk
from tkinter import ttk
def OpenSecondToplevel():
Top2=tk.Toplevel(root)
Top2.geometry("250x200")
Top2.grab_set()
Top2.title("TopLevel 2")
Label = tk.Label(Top2, text="This is Toplevel 2")
Label.pack()
def OpenFirstToplevel():
Top1=tk.Toplevel(root)
Top1.geometry("250x200")
Top1.grab_set()
Top1.title("TopLevel 1")
Button2 = tk.Button(Top1, text="Open Toplevel 2", command=OpenSecondToplevel)
Button2.pack()
root = tk.Tk()
root.title("Main")
root.geometry("250x200")
Frame1 = tk.Frame(root)
Button1 = tk.Button(Frame1, text="Open Toplevel 1", command=OpenFirstToplevel)
Frame1.pack()
Button1.pack()
root.mainloop()
I recorded a video, explaining my issue, because I been looking a lot about Toplevels behavior and I cant seem to find a way to fix it. I hope the video is understandable sorry about the bad English is not my main language, if you have any question you can ask me, thank you!
https://www.youtube.com/watch?v=Ks2zRU0fOJM
For your case, the simple way is to save the current window which has grab_set() in OpenSecondToplevel(), wait for second toplevel to close and then resume the grab_set() state of saved window:
def OpenSecondToplevel():
win = root.grab_current() # save the current window which has grab_set()
# win is None is no window has grab_set()
Top2=tk.Toplevel(root)
Top2.geometry("250x200")
Top2.grab_set()
Top2.title("TopLevel 2")
Label = tk.Label(Top2, text="This is Toplevel 2")
Label.pack()
if win:
# wait until current toplevel is destroyed
win.wait_window(Top2)
# resume grab_set() for saved window
win.grab_set()

How to get the text out of a scrolledtext widget?

I am new to the tkinter python module. I try to do a project. I learned something new about the menus and I'm trying to make a little UI project that allows the user to write something in a scrolled text widget and then save it (using the sys module).
I've already tried some things that worked at buttons. For example .get() but it didn't work. I also tried the ["text"] method.
import tkinter, sys
root = tkinter.Tk()
class saveProject:
def __init__(self, master):
self.master = master
self.textFrame = tkinter.scrolledtext.ScrolledText(self.master, width=100, bd=10, relief="raised")
self.textFrame.pack()
def save(self):
#self.saveText = self.textFrame.get()
self.saveText = self.textFrame["text"]
project = saveProject(root)
root.mainloop()
The problem is, as I already said, I don't know how to get the text out of a tkinter.scrolledtext.ScrolledText widget.
So, out of curiosity I tried what described here (same link in my comment to the OP question). It works also for the scrolledtext.
import tkinter, sys
from tkinter import scrolledtext
root = tkinter.Tk()
class saveProject:
def __init__(self, master):
self.master = master
self.textFrame = scrolledtext.ScrolledText(self.master, width=100, bd=10, relief="raised")
self.textFrame.pack()
self.saveb = tkinter.Button(self.master, text="Save", command= lambda : self.save())
self.saveb.pack()
def save(self):
cur_inp = self.textFrame.get("1.0", tkinter.END)
fl = open("output.txt", "w")
fl.write(cur_inp)
project = saveProject(root)
root.mainloop()
I've added a save button at the bottom of the ScrolledText widget. The widget content is saved inside the output.txt area.
help(ScrolledText) indicates it's a subclass of the tkinter.Text widget, which apparently means that the way to get the text from it is the same — via its get() method using "Text widget indices" (here's some documentation about them).
Below is an example that gets all of the text in the widget (I added a Save text Button to test the save() method):
import sys
import tkinter as tk
from tkinter.scrolledtext import ScrolledText
class SaveProject:
def __init__(self, master):
self.master = master
self.textFrame = ScrolledText(self.master, width=100, bd=10, relief="raised")
self.textFrame.pack()
# Added for testing.
self.save_btn = tk.Button(self.master, text='Save text', command=self.save)
self.save_btn.pack()
def save(self):
self.saveText = self.textFrame.get('1.0', tk.END) # Get all text in widget.
print('self.saveText:', self.saveText)
root = tk.Tk()
project = SaveProject(root)
root.mainloop()

Python: How to create a dialog Window prior to main app Windows

Preface:
I have a Python ControlGPIO code with a working GUI (let us call it MainGUI).
I wish to have a dialog pop up window, prior to running MainGUI, in a way that the user can enable/ disable features in MainGUI. BUT MainGUI should start running only after dialog pop up window is closed.
My question is: How can I make a popup window that will postpone MainGUI untill it is closed?
Code below- boot_windows is my dialog pop up window (where all the enable/disable checkboxes will be ), BUT obviously does not postpone App as I need
root = Tk()
#output_gpioPins = [4,22,6,26]
#input_gpioPins = [3,21,5,27]
#ip = '192.168.2.112'
boot_windows = Toplevel(root)
text1 = ttk.Label(boot_windows, text="Hello World !!!")
text1.grid()
App = ContorlGPIOWindow(root, ip = '192.168.2.113', with_sf_bt=1, with_hw_bt=1, switch_names=['Light Kitchen','Light Room1', 'Window1', 'Window2'])
root.mainloop()
You can't do precisely what you want. Widgets exist in a tree-like structure. All windows except the root require a root window. The root window must be created first (which is why it's called the root window).
If you don't want the user to see it, you can hide it until it is ready to be displayed.
import tkinter as tk
root = tk.Tk()
root.withdraw()
boot_window = tk.Toplevel(...)
...
You can then call root.deiconify() when you are ready for it to be visible.
Another common solution is to use the root window for your dialog or splash screen or whatever, and then simply replace its contents with the real contents when you're ready.
As for how to wait for the popup... the root window has a method named wait_window which will enter the event loop and not return until the given window has been destroyed.
Here's an example of it's use:
import Tkinter as tk
class MainGUI(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="Hello, world!")
label.pack(fill="both", expand=True, padx=20, pady=20)
class Popup(tk.Toplevel):
def __init__(self, root):
tk.Toplevel.__init__(self, root)
label = tk.Label(self, text="Click to continue...")
label.pack(fill="both", expand=True, padx=20, pady=20)
button = tk.Button(self, text="OK", command=self.destroy)
button.pack(side="bottom")
if __name__ == "__main__":
root = tk.Tk()
root.withdraw()
popup = Popup(root)
root.wait_window(popup)
main = MainGUI(root)
main.pack(fill="both", expand=True)
root.deiconify()
root.mainloop()

Python, Tkinter OptionMenu widget & making use of it

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()

Categories

Resources