Thursday, January 8, 2015

Menu Loop

Today I reworked the mainwindow module to handle the Edit menu completely differently. It now creates an Edit menu and disables it. Then it offers these global functions:

def set_up_edit_menu(key, action_list) :
    global _EDIT_MENU, _LAST_KEY
    if key != _LAST_KEY :
        _EDIT_MENU.clear()
        for (title, slot, key) in action_list :
            if title is None :
                _EDIT_MENU.addSeparator()
            else :
                _EDIT_MENU.addAction(title, slot, key)
        _LAST_KEY = key
    _EDIT_MENU.setEnabled(True)

def hide_edit_menu():
    _EDIT_MENU.setEnabled(False)

Any subordinate panel that supports Edit-menu actions such as Copy, must have a focusInEvent() method in which it calls set_up_edit_menu() with a unique key (a letter like "E" for Edit) and a list of triples each of which represents an edit menu action, such as ('Copy',self.copy,QKeySequence.Copy). And I put such code into noteview and editview, and tomorrow will put it in wordview.

In the first version of the above code the final lines were not _EDIT_MENU.setEnabled(True/False) but rather _EDIT_MENU.setVisible(True/False). That produced an amusing result: a hard loop. What was happening was this.

  1. Click in the Notes panel.
  2. Notes panel gets focusInEvent, calls mainwindow.set_up_edit_menu()
  3. Mainwindow changes Edit menu from invisible to visible
  4. Apparently that gives the Edit menu the focus! So...
  5. Notes panel gets focusOutEvent, calls mainwindow.hide_edit_menu()
  6. Mainwindow changes Edit menu from visible to invisible
  7. Qt says, "oh, you didn't want the focus after all? I'll give it back to this noteview widget, then."
  8. Repeat from step 2.

The reason for the complication of passing a key is that I know there will be frequent times when a panel such as the Edit panel will lose the focus to either a different app entirely, or to a panel that doesn't set the edit menu. So if the menu is already set up, just enable and it return.

No comments: