Documents and Views in Pythonwin¶
Existing document
\Pythonwin\doc\docview.html
Todo
see also samples index and add links inline below where referenced
Replace code roles with link to apidocs.
Replace file roles with links to file on github?
Introduction¶
This document describes the document/view architecture of Pythonwin. It is assumed you have read the Pythonwin architecture documentation and are somewhat familiar with the standard MFC architecture.
Wherever possible, Pythonwin and the samples have followed the same architecture as MFC. This has advantages and disadvantages. Often the MFC architecture does not seem to fit with small, short GUI utilities, due to the reliance on “document” based applications. On the positive, Pythonwin can leverage off the full MFC functionality. This means minimal code to get full-blown application support.
Document and View - Control Flow¶
Warning
This needs lots more work. There where 2 flow-charts, which were semi-useless!
The creation of the frame and views are typically done via the PyCWnd.LoadFrame
method. During this call, the windows are created, and virtual functions pass control back to Python. The LoadFrame flow is shown in the separate diagram.
Object Oriented Documents¶
Sam Rushing once asked me “there needs to be a way to create ‘object-oriented’ documents, by that I mean a document with an object associated with it rather than a string. Currently the only way to open a document forces you to use a string (or None
).”
The most obvious path to take would seem to override OpenDocumentFile
or some such, and pass an object rather than a file name. The document could then load itself from the object, and all would be happy. Unfortunately, the tight integration with MFC means this can not work, and led to Sam’s frustration above.
On the other hand, the OpenDocumentFile
method is provided for integration with a standard MDI interface, and the Windows explorer. Obviously, it is not possible to select “File/Open”, and load an object based document.
However, I didn’t have an easy answer for him.
MFC’s OLE Implementation¶
The closest example to the “right” way to do it seemed to be the MFC OLE implementation. When you have an object embedded in another document, and the user wants to edit the object, MFC must load the object without a simple “file name” parameter. MFC’s approach is this:
A normal blank document is created (via
OnNewDocument
)COLEServerDoc’s OLE
XPersistStorage::Load()`
method is called, with an “object” (the OLE storage pointer)- The Documents
OnOpenEmbedding()
method is called. OnOpenDocument
is called, with aNULL
file name parameter.Serialize
is called.
- The Documents
Instead of changing the meaning of the existing functions, MFC adds new definitions for derived classes, such as OnOpenEmbedding
.
Back to our example¶
The cleanest thing seems to be to duplicate the functionality of OpenDocumentFile
- such as OpenObject
. You would do this by:
Check to see if there is already a document representing the document open. If so, switch to it and return.
Create a new document object.
Create a frame for the document
Call
OnNewDocument
to initialise the document.Set the document’s title
Call
InitialUpdateFrame
for the initial display.
objdoc.py
¶
In the Pythonwin demos directory, there is a file objdoc.py
.
This module defines a template, which has an OpenObject
method, and takes any Python object as an argument. If window with the object is already open, it is switched to. If not, a edit window is created, and the object’s __repr__
is written to the window.
Standard virtual function specification¶
Note
I’m not sure where to stick this!
In general, the C++ virtual function handlers follow the same general logic. If no handler is defined, the base class is called. If a Python handler is defined, the base C++ class is not called. In the latter case, it is up to the Python programmer to ensure the base class is called if necessary. This is normally done by calling the method in the underlying _obj_
.