In Chapter 12 we saw a fairly simple framework. The document-view framework allowed one document and one view on that document. In this chapter we will explore more complex configurations.
In this chapter, we will go full tilt immediately, with a framework that supports multiple documents, and with more than one view on those documents. Of course, this means that you have to keep track of which view shows which document. If a document changes, all its views must be updated. If the last view on a document is closed, then the document must be closed. Getting these features right demands quite complex code.
And this is only the conceptual framework. The actual GUI interface is interesting too. There are two or three schools in multiple-document interface design: MDI, MTW, and MTI.
These are cryptic acronyms, but the differences are easy to understand. MDI stands for Multiple Document Interface. This is an interface in which you have several windows inside a an application workspace (which is a window on the desktop). It was invented by Microsoft, who recently tried to bury it. Some users found it rather confusing. However, other users clamored for its return, and Microsoft appears to have appeased their wishes, and reinstated the MDI paradigm in full. As found in most programming environments, in the MDI paradigm there may be both dockable windows that snap to the sides of the main window, and free-floating windows. PyQt supports this way of working with the QWorkSpace class. It's a pity that in PyQt 2 dockable windows are not supported — for that you need to use QDockWindow in PyQt 3.
An MDI workspace
MTW stands for Multiple Toplevel Window. This is more in favor with the Unix/X11 crowd. Here, an application litters the entire desktop with various windows: document windows, floating toolbars, dialog windows — everything. This, too, can be enormously confusing. It works for X11 because most users are sophisticated and have access to a system with multiple desktops. Early versions of Visual Basic also used this strategy, and even now, you can select it as an option.
You can create as many QMainWindow objects in PyQt as you wish, so this style is not a problem at all.
The Gimp littering my desktop
Finally, there is the style made popular by IDE's such as JBuilder. Here, you have your documents in one window, but with a row of tabs that you can use to switch between windows (these tabs are located on the top, bottom or side of the window). There is a legitimate complaint against this style, too: you cannot compare two documents side by side. This style is often used by what I refer to as ‘iso-standard' IDE's: Visual Studio like environments, with a project pane, output pane, and at the top-right corner a stack of tabbed editor windows. BlackAdder conforms, too — except that every project is an MDI-window.
KDevelop — the epitome of an interface with tabs.
I have chosen to disregard the more exotic styles of multiple-document interfaces. There are many varieties of these, such as vi's, in which you have a set of documents you can visit one after another (but not go back) and Emacs, which gives you a set of buffers that may or may not be presented in another window or another frame (where window and frame are the exact opposite of what you'd expect). These oddities should remain just that — oddities.
As an aside, it is interesting to note that all these styles originated with programming environments. It is often the case that a programming environment influences the developer in his interface decisions — and this might very well fail to support the needs of the user...
In this chapter, we first develop a document/view manager that can be used to manage a situation in which you have more than one document with more than one view. It will also handle keeping track of modifications to the documents, saving, saving under a new filename, and closing documents without saving. This is quite complex enough for now; in the next chapter, we will investigate the addition of switchable interface styles. After that we will have, at last, a framework that we can add a real application to.