PyLan a GTD todo application written in python and PyGTK – part four context menus!


PyLan Four

Hello welcome to the fourth installment of the PyLan tutorial. This will be a quick tutorial to introduce one feature: context (or popup) menus. I’ve had many questions regarding this so I thought I would take a quick stab at it.

If you want to follow along with the code in detail, and have not done so already, you should read part one, part two and part three of this series.

You can download the full source to this tutorial here.

Python GTD pyGTK

This tutorial is organized into the following sections:

  1. Adding the menu in Glade
  2. Showing the menu in Python

Adding the menu in Glade

So let’s startup glade and create a new popup menu item. Add the following four items to the menu:

  1. New Category. Name – “new_category_menu” Handler – “on_add_category”
  2. New Task. Name – “new_task_menu” Handler – “on_add_task”
  3. _Edit. Name – “edit_context_menu” Handler – “on_edit_object”
  4. _Remove. Name – “remove_context_menu” Handler – “on_remove_item”

Call the menu itself: contextMenu

That’s it for glade.

Showing the menu in Python

The first thing that we need to do is get the menu widget in our initialize_widgets() function:

#load the menu from the glade file
wTree = gtk.glade.XML(self.gladefile, "contextMenu")
#connect the menu with the signals
wTree.signal_autoconnect(self)
#Get the menu dialog widget
self.context_menu = wTree.get_widget("contextMenu")

Now that we have the widget we need to actually show it when people right-click on our TreeView. We didn’t have to add a button press handler to our TreeView because we added one in the last tutorial, but we will have to edit it.

Here is the original function:

def on_todoTree_button_press_event(self, widget, event):
	"""There has been a button press on the TodoTree
	for now we use this as a quick hack to remove
	the selection.  Perhaps there is a better way?
	@param widget - gtk.TreeView - The Tree View
	@param event - gtk.gdk.event - Event information
	"""
	#Get the path at the specific mouse position
	path = widget.get_path_at_pos(int(event.x), int(event.y))
	if (path == None):
		"""If we didn't get apath then we don't want anything
		to be selected."""
		selection = widget.get_selection()
		selection.unselect_all()

We will have to change this function to show our menu widget, which is a pretty simple addition to the end of the function:

if (event.button == 3):
	#This is a right-click
	self.context_menu.popup( None, None, None
		, event.button, event.time)

Python GTD pyGTK

So far so good, you’ll notice that since the menu handlers are the same as our toolbar handlers everything already works! The only problem is that the sensitive state of the menu items does not match the sensitive state of the toolbar buttons.

Thankfully since we added this feature to the buttons in the last tutorial doing this is pretty easy.

The first thing that we need to do is get the menu items and disable them in the same way that we do the buttons in the initialize_widgets() function:

#Get the menu widgets
self.new_category_menu = wTree.get_widget("new_category_menu")
self.new_task_menu = wTree.get_widget("new_task_menu")
self.edit_context_menu = wTree.get_widget("edit_context_menu")
self.remove_context_menu = wTree.get_widget("remove_context_menu")

#disable them like the buttons
self.new_task_menu.set_sensitive(False)
self.edit_context_menu.set_sensitive(False)
self.remove_context_menu.set_sensitive(False)

Then in the on_tree_selection_changed() function we need to update the menu items sensitive state:

self.new_task_menu.set_sensitive((selection_iter != None))
self.edit_context_menu.set_sensitive((selection_iter != None))
self.remove_context_menu.set_sensitive((selection_iter != None))

Now we have nice context menus!

Python GTD pyGTK

You can download the full source to this tutorial here.

selsine

del.icio.us del.icio.us

9 Responses to “PyLan a GTD todo application written in python and PyGTK – part four context menus!”

  1. lrf
    Says:

    Warning!

    Link to ‘Part two’ of article turns out into “Error 404 – Not Found”; a fix is needed.

    Tks

  2. selsine

    selsine
    Says:

    Hi Irf,

    Thanks for the catch, I have fixed the link.

  3. Matthew Nuzum
    Says:

    Hi, I’ve come to your site in a round-about way from a site about autoglade. I see your articles on pyGTK hold the answers to some questions I’ve had for a while and I look forward to working through them.

    But I have to ask, what is the window/gtk theme you’re using in these screenshots? It looks very elegant and I’d like to try it out.

  4. selsine

    selsine
    Says:

    HI Matthew, right now I’m using Darkilouche as my theme.

  5. Jan Willems
    Says:

    Great tutorial. Thanks a mil!

  6. Preben
    Says:

    Hi

    I like the program so I wanted to try to use it. Problem is that after saving the todo list and opening the program again it won’t load the todo list. I get Error opening file

    When I change the code in load_from_file to

    except Exception, e:
    helper.show_error_dlg(_(“Error opening file: %s\r\n%s”) % (filename, e))
    return False

    I get the additional infor: No module named todo

  7. Preben
    Says:

    The above error occurs in Windows XP it seems. I used Python 2.5. In Debian GNU/Linux it works with both 2.4 and 2.5.

    Any idea?

  8. Preben
    Says:

    Found the bug. In the save_to_file function the todo_file is opened with “w”. According to the manual it needs to be opened with “wb” when using cPickle and dump.

    So the line should read:
    todo_file = open(filename, “wb”)

  9. selsine

    selsine
    Says:

    Hi Preben,

    Thanks! Great catch! Sorry I wasn’t able to respond to your comments yesterday, but I’m really glad that you found the problem. I will update the source when I get a free moment.

    At some point in time I should use some source code repository so that people can make changes and fix it up themselves.

Leave a Reply

 

Popular Posts