
I want to construct a context menu with a menu item for selecting a date. (The use case is selecting a bunch of items in a treeview and then setting a new due date for all the items.)
Since a menuitem is a Gtk.Bin, I can specify any widget in place of a label. However, I can’t seem to interact with the widget. If I click anywhere on the menu, the menuitem gets the click. So, I can’t select a particular date, nor navigate months or years. How can I make the calendar get the mouse activity?
Also, there is extraneous padding around the outside of the calendar, and when hovered over it turns orange. How can I remove the padding and/or not do the orange highlight?
#!/usr/bin/env python
import gobject
import pygtk
pygtk.require('2.0')
import gtk
import time
class ContextMenu(gtk.Menu):
def __init__(self):
gtk.Menu.__init__(self)
def add_calendar_submenu_item(self, text, callback, uuids, data=None):
calendar = gtk.Calendar()
calendar.show()
calendar_item = gtk.MenuItem()
calendar_item.add(calendar)
calendar_item.show()
submenu = gtk.Menu()
submenu.append(calendar_item)
submenu_item = gtk.MenuItem("%s..." %(text))
submenu_item.set_submenu(submenu)
submenu_item.show()
submenu_item.connect("activate", self.on_calendar_activate)
self.append(submenu_item)
def on_calendar_activate(self, widget):
print "activate"
if __name__ == "__main__":
class CalendarExample:
def __init__(self):
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
window.set_title("Calendar Example")
window.set_border_width(5)
window.set_size_request(200, 100)
window.set_resizable(False)
window.stick()
window.connect("destroy", lambda x: gtk.main_quit())
menu = ContextMenu()
menu.add_calendar_submenu_item("date", self.on_date, ['123'])
root_menu = gtk.MenuItem("Calendar Menu")
root_menu.show()
root_menu.set_submenu(menu)
vbox = gtk.VBox(False, 10)
window.add(vbox)
vbox.show()
menu_bar = gtk.MenuBar()
vbox.pack_start(menu_bar, False, False, 2)
menu_bar.append (root_menu)
menu_bar.show()
button = gtk.Button("Push Me")
button.connect("clicked", self.on_menu_push, menu)
vbox.pack_start(button, False, True, 10)
button.show()
window.show()
def on_menu_push(self, widget, menu):
menu.popup(None, None, None, 0, 0)
def on_action(self, widget, uuids, text):
print "Item %s pressed" %(text)
def on_date(self, widget, uuids, text):
print "Calendar activated with %s" %(text)
CalendarExample()
gtk.main()
[Update]
What I’m going for is something akin to Ubuntu’s indicator menu date/time calendar.

As already mentioned by ilius in the comments, menu is not designed to hold arbitrary widget. It has also been discussed in this SO post. You will have to go with the pop-up window option.
The clock applet in Ubuntu which you are trying to emulate uses pop-up window. You can verify this using
xwininfo. If you have the calendar displayed then select it (forxwininfoutility) you can see that it is a separate window and not the same as the panel.Further, this can be confirmed by looking at the source. The clock applet which is shown is a toggle button which on toggle shows/hides the pop-up window with calendar (more precise it is a custom widget
CalendarWindowwhich extendsGtkWindowand addsGtkCalendarappropriately when created). A crude implementation of the same idea based on your code is as follows (Please pardon my limited python knowledge):Hope this helps!