I want to have a menu that shows a modal dialog box. Everything is fine, until I add an accelerator. If I do this and use the accelerator to access to dialog, it hangs. I suspect that wait_window, used inside the modal dialog box is somehow in conflict with the mainloop, when called from a "bind". Here is an example:
import tkinter
from tkinter import simpledialog
class App(tkinter.Tk):
def __init__(self):
tkinter.Tk.__init__(self)
self.bind_all("<Control-f>", lambda event: self.menu_file())
menubar = tkinter.Menu(self)
fileMenu = tkinter.Menu(menubar, tearoff=False)
fileMenu.add_command(label="File", underline=0,
command=self.menu_file, accelerator="Control+f")
# fileMenu.add_command(label="File", underline=0,
# command=self.menu_file)
menubar.add_cascade(label="File",underline=0, menu=fileMenu)
self.config(menu=menubar)
def menu_file(self):
simpledialog.Dialog(self,"Message")
app=App()
app.mainloop()
If in the above code I comment out the line that adds the accelerator and uncomment the subsequent line, there is no hangup (I can of course still use Ctrl+F to access the dialog box). The only problem is that the accelerator string is not shown next to the File menu. According to the tkinter documentations on the web that I have found, adding the accelerator should only change how the menu is shown and nothing else, so I am really puzzled. Anyone any ideas? (I could of course emulate accelerators by modifying the strings to be displayed, but I would not consider this as an elegant solution.)
As I have noticed, this is a Mac-specific bug. Following the workaround suggested for a known Tk bug on Mac (see link), changing the line which binds the menu method to the keystroke to the following:
self.bind_all("<Command-f>", lambda event: self.after(100,self.menu_file))
is "fixing" the bug. They also suggest to increase 100 to 150 on slower systems. Hmm..