Menus

Most of the time, you can simply add actions or action groups to menus. This is what we did above, in the docview framework. However, in some cases it is desirable to have a dynamic list of menu options. This is a bit more complicated. This is useful, for instance, in applications where the user can open more than one window, or for lists of recently opened files. In almost every other case, it is awfully confusing to the user if menu options are added and removed at the whim of the application.

By connecting the aboutToShow() signal of a menu to a slot (for example, slotWindowMenuAboutToShow), you can exercise precise control over the contents of the menu by first clearing it, and then building it up again. Note the use of setItemChecked() to place a checkmark next to selected windows. This is something you get for free with a QActionGroup, but recreating a QActionGroup every time the user selects the window menu is just as much a bore as recreating the menu, if not more so.

  def slotWindowMenuAboutToShow(self):
        self.windowMenu.clear()
        self.actions["windowNewWindow"].addTo(self.windowMenu)
        self.actions["windowCascade"].addTo(self.windowMenu)
	self.actions["windowTile"].addTo(self.windowMenu)
        if self.workspace.windowList()==[]:
            self.actions["windowAction"].setEnabled(FALSE)
        else:
            self.actions["windowAction"].setEnabled(TRUE)
        self.windowMenu.insertSeparator()

        i=0 # window numbering
        self.menuToWindowMap={}
        for window in self.workspace.windowList():
            i+=1
            index=self.windowMenu.insertItem(("&%i " % i) +
                                             str(window.caption()),
                                             self.slotWindowMenuActivated)
            self.menuToWindowMap[index]=window
            if self.workspace.activeWindow()==window:
                self.windowMenu.setItemChecked(index, TRUE)

    def slotWindowMenuActivated(self, index):
        self.menuToWindowMap[index].setFocus()
      

We will investigage the creation of application frameworks containing more than one window in chapter Chapter 15.