Trying to make a tkinter menu button that do multiple tasks - python

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)

Related

Tkinter pack_forget() and destroy() don't work

I have a problem with these two functions that don't work as expected.
I want to use a selection form drop-down menù and based on the selection two different set of checkbox are displayed in the root window. To do so, I use this code:
from tkinter import *
import tkinter as tk
def evaluation(form):
form.pack_forget()
form.destroy()
form=Frame(root)
GotPlatform=platform.get()
for elem in PlatformOption[GotPlatform]:
OptionButtonSel[elem]=Checkbutton(form, text=elem)
OptionButtonSel[elem].pack()
form.pack(fill="both", expand = 1)
PlatformOption={'Option1':["option1-1","option1-2"],'Option2':["option2-1","option2-2"]}
OptionButtonSel={}
root = tk.Tk()
f1=Frame(root)
menuBar = tk.Menu(root)
menu1 = tk.Menu(root)
submenu = tk.Menu(root)
platform = StringVar()
submenu.add_radiobutton(label="Option1", value="Option1", variable=platform,command=lambda:evaluation(f1))
submenu.add_radiobutton(label="Option2", value="Option2", variable=platform,command=lambda:evaluation(f1))
menuBar.add_cascade(label="Options", menu=menu1)
menu1.add_cascade(label="Select option", menu=submenu)
root.config(menu=menuBar)
root.mainloop()
The code works but whenever I change the options fron drop-down menù, the checkboxes option are stacked and aren't overwritten as expected.
This puzzles me since I have used this other code and it works as expected:
from tkinter import Tk, Frame, Menu, Label
def show_frame1():
forget_all()
f1.pack(fill="both", expand = 1)
def show_frame2():
forget_all()
f2.pack(fill="both", expand = 1)
def forget_all():
f1.pack_forget()
f2.pack_forget()
root = Tk()
f1 = Frame(root)
f2 = Frame(root)
Label(f1, text="MENU SELECTED 1").pack()
Label(f2, text="MENU SELECTED 2").pack()
menubar=Menu(root)
subMenu=Menu(menubar, tearoff = 0)
menubar.add_cascade(label = 'MENU', menu=subMenu)
subMenu.add_command(label = 'SUBMENU1', command = show_frame1)
subMenu.add_command(label = 'SUBMENU2', command = show_frame2)
root.config(menu = menubar)
root.mainloop()
Aside from addind destroy(), the usage of frame and pack_forget() seems identical to me.
I use Python 3.10.1, IDE Spyder last version, Windows 8.
The root of the problem is that you create a form that never appears on the screen. You create it, but never call pack on it. You then pass this form to the function every time the button is clicked. In other words, you keep passing the original form, not the new one that is recreated.
The best solution is for your main code to call pack, place, or grid on the form, and then in the function you can delete the children of the form without deleting the form itself.
So, add the following shortly after creating f1:
f1.pack(fill="both", expand=True)
Next, modify evaluation to destroy the children rather than the form itself:
def evaluation(form):
for child in form.winfo_children():
child.destroy()
GotPlatform=platform.get()
for elem in PlatformOption[GotPlatform]:
OptionButtonSel[elem]=Checkbutton(form, text=elem)
OptionButtonSel[elem].pack()
It gives the effect that it doesn't work because the widget is invisible to the screen. This topic however is further explained below
pack_forget() not working
Just to prove my theory I did some other research about the topic and
https://www.geeksforgeeks.org/python-forget_pack-and-forget_grid-method-in-tkinter/
explains the concept of pack_forget() perfectly

disable buttons and menu bar when calling subprocess then enable them in tkinter

i want to disable buttons when i call subprocess to execute another tkinter window and to prevent multi-showing windows when i click too many times on buttons, then after finishing from the second calling window i want to re-enable them.
menubar.entryconfig("tester", state="disabled") and
menubar.entryconfig("tester", state="normal")
both of them in the same function does not ndo the trick. is there any other way to do it. And thanks in advance.
# add the necessairy librairy
import tkinter as tk
import subprocess
def Region_windows2():
menubar.entryconfig("tester", state="disabled")
menubar.entryconfig("tester2", state="disabled")
menubar.entryconfig("tester3", state="disabled")
subprocess.call(['/home/pi/test3/script.sh'])
menubar.entryconfig("tester", state="normal")
# here's the main window
Mafenetre = tk.Tk()
#set main window title
Mafenetre.title("GUI")
Mafenetre['bg']='white' # couleur de fond
# get screen width and height
wf1= Mafenetre.winfo_screenwidth()
hf1= Mafenetre.winfo_screenheight()
A = str(wf1)
B = str(hf1)
# set the dimensions of the screen
# and where it is placed
Mafenetre.geometry(A+"x"+B)
Mafenetre.attributes('-fullscreen', True)
# add menubar to the main window
menubar = tk.Menu(Mafenetre, bg='#1f1b13', fg='white')
# menubar button to test the second window
menubar.add_command(label="tester", command=Region_windows2)
menubar.add_command(label="tester2", command=hello)
menubar.add_command(label="tester3", command=hello)
# add menubr to the main window
Mafenetre.config(menu=menubar)
pwd = tk.Entry(Mafenetre, show="*")
pwd.pack()
pwd.focus()
Mafenetre.mainloop()

Why isn't the menu showing up? - Tkinter

I'm trying to do a menu using tkinter. But when I run the code, the window appears, but the menu doesn't. I'm getting no errors.
Here is my code:
from tkinter import *
root = Tk()
root.geometry("500x300")
menu = Menu(root)
file_menu = Menu(menu, tearoff=0)
file_menu.add_command(label="New")
file_menu.add_command(label="Open")
file_menu.add_command(label="Save")
menu.add_cascade(label="File", menu=file_menu)
menu
root.mainloop()
You haven't added it to the root window. You need to do the following after creating menu:
root.configure(menu=menu)

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

How do I give focus to a python Tkinter text widget?

I'd like to be able to open the App GUI and have it automatically place the cursor into a particular text widget. Best case scenario is: as soon as the app is launched someone can start typing without having to click on the text widget. This is just a small example displaying the issue:
from Tkinter import *
root = Tk()
Window = Frame(root)
TextWidget = Text(Window)
TextWidget.pack()
Window.pack()
root.mainloop()
You use the focus_set method. For example:
from Tkinter import *
root = Tk()
Window = Frame(root)
TextWidget = Text(Window)
TextWidget.pack()
Window.pack()
TextWidget.focus_set()
root.mainloop()

Categories

Resources