pythonmenutkintermodal-dialogaccelerator

tkinter menu accelerators and modal dialog boxes


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


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..