Question

For my Tkinter GUI, I have already created a Menu and a Status Bar. However, how to display description when mouse is over menu items?

Please run the following code (eg. when mouse is over menu item "About", status bar should write "Information":

from Tkinter import Tk, Frame, BOTH, Menu, Label, SUNKEN, X, BOTTOM

class Application(Frame):
   def __init__(self, parent):
      Frame.__init__(self, parent, background = "white")
      parent.configure(bg = "black")
      self.pack(fill = BOTH, expand = True, padx = 20, pady = 20)

      self.parent = parent

      # Maximize window
      self.screenWidth = self.parent.winfo_screenwidth() - 5
      self.screenHeight = self.parent.winfo_screenheight() - 110
      self.parent.geometry('%dx%d+%d+%d' % (self.screenWidth, self.screenHeight, 0, 0))
      self.parent.resizable(0, 0)

      # Status bar
      self.statusBar = StatusBar(self.parent)
      self.statusBar.pack(side = BOTTOM, fill = X)

      # Menu bar
      menubar = Menu(self.parent)
      self.parent.config(menu = menubar)

      self.commandMenu = Menu(menubar, tearoff = 0)
      self.commandMenu.add_command(label = "Rename", command = self.onRename)
      menubar.add_cascade(label = "Command", menu = self.commandMenu)

      self.helpMenu = Menu(menubar, tearoff = 0)
      self.helpMenu.add_command(label = "About", command = self.onAbout)
      menubar.add_cascade(label = "Help", menu = self.helpMenu)

   def onRename(self):
      pass
   def onAbout(self):
      pass

class StatusBar(Frame):
   def __init__(self, master):
      Frame.__init__(self, master)
      self.label = Label(self, bd = 1, relief = SUNKEN, anchor = "w")
      self.label.pack(fill=X)
   def set(self, format0, *args):
      self.label.config(text = format0 % args)
      self.label.update_idletasks()
   def clear(self):
      self.label.config(text="")
      self.label.update_idletasks()

def main():
   root = Tk()
   Application(root)
   root.mainloop()

if __name__ == '__main__':
   main()  
Was it helpful?

Solution

So, the thing you're looking for is the <<MenuSelect>>.

If you bind the self.helpMenu to <<MenuSelect>>, like in my update of your code:

__author__ = 'rcope'
from Tkinter import Tk, Frame, BOTH, Menu, Label, SUNKEN, X, BOTTOM

class Application(Frame):
   def __init__(self, parent):
      Frame.__init__(self, parent, background = "white")
      parent.configure(bg = "black")
      self.pack(fill = BOTH, expand = True, padx = 20, pady = 20)

      self.parent = parent

      # Maximize window
      self.screenWidth = self.parent.winfo_screenwidth() - 5
      self.screenHeight = self.parent.winfo_screenheight() - 110
      self.parent.geometry('%dx%d+%d+%d' % (self.screenWidth, self.screenHeight, 0, 0))
      self.parent.resizable(0, 0)

      # Status bar
      self.statusBar = StatusBar(self.parent)
      self.statusBar.pack(side = BOTTOM, fill = X)

      # Menu bar
      menubar = Menu(self.parent)
      self.parent.config(menu = menubar)

      self.commandMenu = Menu(menubar, tearoff = 0)
      self.commandMenu.add_command(label = "Rename", command = self.onRename)
      menubar.add_cascade(label = "Command", menu = self.commandMenu)

      self.helpMenu = Menu(menubar, tearoff = 0)
      self.helpMenu.add_command(label = "About", command = self.onAbout)
      menubar.add_cascade(label = "Help", menu = self.helpMenu)
      self.helpMenu.bind("<<MenuSelect>>", self.statusBarUpdate)

   def onRename(self):
      pass
   def onAbout(self):
      pass

   def statusBarUpdate(self, event=None):
       print "Status Bar Update Called"
       if self.parent.call(event.widget, "index", "active") == 0:
           self.statusBar.set("About This Application")
       else:
           self.statusBar.set("")

class StatusBar(Frame):
   def __init__(self, master):
      Frame.__init__(self, master)
      self.label = Label(self, bd = 1, relief = SUNKEN, anchor = "w")
      self.label.pack(fill=X)
   def set(self, format0, *args):
      self.label.config(text = format0 % args)
      self.label.update_idletasks()
   def clear(self):
      self.label.config(text="")
      self.label.update_idletasks()

def main():
   root = Tk()
   Application(root)
   root.mainloop()

if __name__ == '__main__':
   main()

The only thing you need to keep track of now, is what index corresponds to what menu item. I would recommend keeping an int you increment each time you add a menu entry, and using each index via a dict to get whatever relevant information about the menu item you need. Tkinter doesn't tell you a lot through the entry in the statusBarUpdate callback (like that this was called from the menu command labeled "About"), so you need to roll this yourself, I think.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top