Tkinter menu copy/paste/cut option - python

I have coded in that when you right click you get a menu With copy/cut/paste after some googeling, but i havent found anything about a dropdown menu With copy/cut/paste...
What i got:
from Tkinter import *
master = Tk()
Edit.add_command(label="Copy")
Edit.add_command(label="Paste")
Edit.add_command(label="Cut")
bar.add_cascade(label="Edit", menu=Edit)
mainloop()
Notes:
I am coding in Python 2.7

You need to create a menubar,
mymenu = Menu(master)
create the Edit menu,
editmenu = Menu(mymenu, tearoff=0) # editmenu is now a child of mymenu
add your menu options with labels and commands,
editmenu.add_command(label='Cut', command=cut) # 'cut' is a cut function you wrote
editmenu.add_command(label='Copy', command=copy) # need a copy function too
editmenu.add_command(label='Paste', command=paste) # paste function
then add that Edit menu to the menubar,
mymenu.add_cascade(label='Edit', menu=editmenu)
then add the menubar to the master tk object:
master.config(menu=mymenu)
Then a menubar will appear at the top of the window when you run the program. Make sure you define the cut, copy, and paste functions, or you'll get an error. You can use print as a placeholder if you want.

Related

How do you close all Tkinter windows when specific window closes?

I have this application in Python Tkinter. There is a Python file which is a main menu. When I click an option in the main menu it imports a python file with code that makes a new window (couldn't use Toplevel for the new window for some reasons). So when I close the main menu it should close all the other windows.
Here is my code for the main menu:
from tkinter import *
root = Tk()
root.geometry("600x600")
def newWindowImport():
import file1
def newWindowImport2():
import file2
newWindow = Button(text="new window", command=newWindowImport).pack()
newWindow2 = Button(text="new window", command=newWindowImport2).pack()
# Here is there a way so that when I exit it destroys the Main Menu as well as the opened windows
exitBtn = Button(text="Exit", command=root.destroy())
root.mainloop()
I tried the root.destroy method but it only destroys the main menu and not all the windows. Is there a way so that when I exit the main menu it destroys the main menu as well as the opened windows? If I were to use Toplevel - how would I use it in a separate file?
I am assuming that your other scripts have individual instances of Tk(), their own mainloop() and are not under a function, if that is the case, you can have all the code in your files under a function and use Toplevel(), example, file1 should look like
def something():
window=Toplevel()
#Rest of the code
And similarly file2, after that in your main program you could do something like this
from tkinter import *
import file1, file2
root = Tk()
root.geometry("600x600")
def newWindowImport():
file1.something()
def newWindowImport2():
file2.something()
newWindow = Button(text="new window", command=newWindowImport)
newWindow.pack()
newWindow2 = Button(text="new window", command=newWindowImport2)
newWindow2.pack()
# Here is there a way so that when I exit it destroys the Main Menu as well as the opened windows
exitBtn = Button(text="Exit", command=root.destroy)
root.mainloop()
You could also let go of the functions and make these changes to have it shorter
newWindow = Button(text="new window", command=file1.something)
newWindow.pack()
newWindow2 = Button(text="new window", command=file2.something)
newWindow2.pack()
The reason for your approach not working would be that each file had it's own mainloop() and hence they couldn't be destroyed when you called root.destroy in the main code.
Also note that I have removed the parentheses () from the command=root.destroy otherwise the it will be called as soon as the program initializes.
EDIT : As also suggested by #martineau in the comments, it's better to use .pack() on the Button instances separately as it provides more flexibility in using the instance later in the program, as opposed to having them hold the value None which is the return from .pack()
Using Toplevel is the correct way to do this, you need to find out why that is not working and correct it. If you did that this question would solve itself. Also, you need to remove the () from the command, it should be like this:
exitBtn = Button(text="Exit", command=root.destroy)

How call a function in a Tkinter menu

I would like to call a function clicking on fileMenu 'Action', I was able to call the function (below is just one example) only by entering it in the submenu, is there a way for make it?
import tkinter as tk
from tkinter import Menu
def stateMenu():
fileMenu.entryconfig("Delete", state="disabled")
fileMenu.entryconfig("Transfer", state="disabled")
root = tk.Tk()
menubar = Menu()
fileMenu = Menu(menubar, tearoff=0)
menubar.add_cascade(label="Action", menu=fileMenu) // I would like call function here
fileMenu.add_command(label="Delete", command=stateMenu, state="normal") // no here
fileMenu.add_command(label="Transfer", command=stateMenu, state="normal") // no here
root.config(menu=menubar)
root.mainloop()
The only way to call a command from a menubar is by adding the command with add_command. Some operating systems allow you to add commands to the root menubar, some don't.
From a usability perspective it's generally considered a bad idea to add commands directly on the menubar. Users expect to see a menu when they click on something on the menubar, and would be surprised if some action immediately happened.

Menu bar does not show up on macOS

I wrote this code on Pycharm (macOS) but the menu bar does not show up. Can anyone tell me why?
from tkinter import *
root = Tk()
def hello():
print("hello!")
# create a toplevel menu
menubar = Menu(root)
menubar.add_command(label="Hello!", command=hello)
menubar.add_command(label="Quit!", command=root.destroy)
# display the menu
root.config(menu=menubar)
root.mainloop()
You cannot put commands at the very top of a menubar in OSX. Also, the menu will not appear at the top of the window, it appears at the top of the screen just like with native OSX apps.
Other than the fact that your menubar has no dropdown menus, it's working as designed. Add a dropdown menu, and that menu will appear on the menubar.

How to disable a tkinter OptionMenu

I can't figure out or find how to disable a tkinter OptionsMenu. I have 3 optionsmenu's in my GUI and want to disable them when a button is clicked
self.menu = OptionMenu(self, var, *items)
btn = Button(self, text="disable", command = self.disable)
btn,pack()
self.disable(self):
//Disable menu here...
Is there a way to just call a built in function for OptionMenu and disable it? Or do I have to disable every option in the menu? (Which i also can't figure out)
BTW: I used the menu.pack() for a separate Topleve() window that pops up, but I started off with the grid() system in my main Tk window, used by menu.grid(row=0,column=0)
EDIT:
So I forgot to mention that I have multiple OptionMenus being generated by a constructor method. This is what I tried doing and didn't work:
makeMenu():
menu = OptionMenu(self, var, *items)
....//whole bunch of menu settings
return menu
menu1 = makeMenu()
all_menus.append(menu)
Now the reason this didn't work is because I had to append it after creation. I don't know why the settings don't carry over, but what I had to do is this:
makeMenu():
menu = OptionMenu(self, var, *items)
....//whole bunch of menu settings
return menu
makeMenu():
menu = OptionMenu(self, var, *items)
....//whole bunch of menu settings
all_menus.append(menu)
makeMenu()
And with this change, I can use this to disable menus later on:
for menu in all_menus:
menu.config(state=DISABLED)
Like with any other widget, you use the configure method to set the state to "disabled":
self.menu.configure(state="disabled")
The above will work for both the tkinter and ttk OptionMenu widgets.

Keep a menu open in Tkinter

I want to keep a menu cascade open, after a command button within the cascade is clicked. So it basically only closes when the user clicks anywhere else (like it would normally too). Can't seem to find a proper option or a method to open said menu in the callback. The invoke() function only works on buttons wihtin the cascade right? How would you go about that?
Yes, I know this was asked a long time ago, but I was curious if there was any way to accomplish this with tkinter, so I fiddled about for a while and figured out how to do it. I was unable to come up with a way to properly place the persistent menu where it was when it originally opened, but I have managed to make it persist in any location you request (I use upper-left corner of root window). And yes, I know this isn't a nice proper class based implementation, but I was just going for as simple a test as I could write without obscuring it with too many extraneous details.
try:
from tkinter import *
from tkinter.ttk import *
except:
from Tkinter import *
from ttk import *
root = Tk()
var = StringVar()
def menu_click(menu, item):
global root
var.set(item)
menu.post(root.winfo_rootx(), root.winfo_rooty())
root.option_add('*tearOff', False) # remove tearoff from all menus
Label(root, textvariable=var).pack() # just to give menu clicks some feedback
root.geometry('400x300')
menubar = Menu(root)
root['menu'] = menubar
menu_test = Menu(menubar)
menubar.add_cascade(menu=menu_test, label='Test')
menu_test.add_command(label='One', command=lambda: menu_click(menu_test, 'One'))
menu_test.add_command(label='Two', command=lambda: menu_click(menu_test, 'Two'))
menu_test.add_command(label='Three', command=lambda: menu_click(menu_test, 'Three'))
menu_cas = Menu(menu_test)
menu_test.add_cascade(menu=menu_cas, label='Four')
menu_cas.add_command(label='One', command=lambda: menu_click(menu_cas, 'Fourty One'))
menu_cas.add_command(label='Two', command=lambda: menu_click(menu_cas, 'Fourty Two'))
menu_cas.add_command(label='Three', command=lambda: menu_click(menu_cas, 'Fourty Three'))
root.mainloop()

Categories