index.lxp@lxpwrap=x5388_252ehtm.htm

来自「GUI Programming with Python」· HTM 代码 · 共 576 行 · 第 1/2 页

HTM
576
字号
      closed! If this view is the first, then it it will be maximized.      This is one area where the docmanager still assumes a      traditional MDI paradigm &#8212; we'll massage this out in the      next chapter. Note also that we keep count of the number of      views in each document, and then set the caption      accordingly.</P><P>Note also that we &#8216;install' the event      filter of the parent object &#8212; that is, the application      &#8212; in the view. This overrides the default event handling      of the view object, and makes it possible to use the document      manager object.</P><PRECLASS="PROGRAMLISTING">    def createDocument(self, documentClass, viewClass):        document = documentClass()        view = self._createView(document, viewClass)        if self._docToViewMap.has_key(document):            self._docToViewMap[document].append(view)        else:            self._docToViewMap[document] = [view]        self._viewToDocMap[view] = document        self.emit(PYSIGNAL("sigNumberOfDocsChanged"),())        return document    </PRE><P>The <TTCLASS="FUNCTION">createDocument(self,        documentClass, viewClass)</TT> command actually      instantiates the document. When that's done, a view is created      and mapped to the document. Note the signal we emit here: it can      be useful for the application object to know that the number of      documents has been changed. For instance, the "save" menu option      must be enabled when the first document is created.</P><PRECLASS="PROGRAMLISTING">    def addView(self, document, viewClass):        if self._docToViewMap.has_key(document):            view = self._createView(document, viewClass)            self._docToViewMap[document].append(view)            self._viewToDocMap[view] = document            return view        else:            raise DocManagerError(document)    </PRE><P>Adding a new view to an existing document      is fairly simple: just create the view and map it to a document,      and vice versa. Note that if the document does not exist, we      raise a <TTCLASS="CLASSNAME">DocManagerError</TT> &#8212; the      document object apparently doesn't belong to this      manager.</P><PRECLASS="PROGRAMLISTING">    def addDocument(self, document, viewClass):        view = self._createView(document, viewClass)                    if self._docToViewMap.has_key(document):            self._docToViewMap[document].append(view)        else:            self._docToViewMap[document] = [view]        self._viewToDocMap[view] = document        self.emit(PYSIGNAL("sigNumberOfDocsChanged"),())        return view    </PRE><P>Of course, it must be possible to add an      existing document to the document manager. This is used when the      user opens a document.</P><PRECLASS="PROGRAMLISTING">    def activeDocument(self):        if self._viewManager.activeWindow() is not None:            return self._viewToDocMap[self._viewManager.activeWindow()]        else:            return None    </PRE><P>Since the      <TTCLASS="CLASSNAME">QWorkSpace</TT> class, which is the model for      the view manager, knows which window is active, we can use that      to determine which document is active.</P><PRECLASS="PROGRAMLISTING">    def _saveDocument(self, document):        if document.pathName() == None:            document.setPathName(self._parent.queryFileName(document))        try:            document.save()        except Exception, e:            QMessageBox.critical(self,                                 "Error",                                 "Could not save the current document: " + e)            raise e    </PRE><P>The things that can go wrong when trying      to save a document are manifold &#8212; however, we assume that      the document knows when to shout "Exception". If that happens,      the user is informed, and the exception re-raised.</P><PRECLASS="PROGRAMLISTING">    def _queryCloseDocument(self, document):        if self._parent.queryCloseDocument(document) == QMessageBox.No:            return FALSE        if document.modified():            save = self._parent.querySaveDocument(document)            if save == QMessageBox.Yes:                try:                    self._saveDocument(document)                    return TRUE                except Exception, e:                    if self._parent.queryDiscardDocument(document) &#60;&#62; \                       QMessageBox.Yes:                        return FALSE                    else:                        return TRUE            elif save == QMessageBox.No:                return TRUE            elif save == QMessageBox.Cancel:                return FALSE        return TRUE    </PRE><P>The aim of      <TTCLASS="FUNCTION">_queryCloseDocument</TT> is to determine what      the user really wants when he closes a document&#8212;an action      that can throw quite a few wobblies. At every step the function      asks the user what he wants. Does he want to save the data? And      in case saving doesn't succeed, does he want to discard the      document? Or would he prefer to keep the document open, and go      on throwing foul looks at an application that contains his      precious data, which he cannot save? </P><PRECLASS="PROGRAMLISTING">    def _removeView(self, view, document):        try:            self._docToViewMap[document].remove(view)            del self._viewToDocMap[view]        except ValueError, e:            pass # apparently already deleted    def closeView(self, view):        document=self._viewToDocMap[view]        if len(self._docToViewMap[document])==1:            if self._queryCloseDocument(document):                self._removeView(view, document)                del self._docToViewMap[document]                return TRUE            else:                return FALSE        else:            self._removeView(view, document)            return TRUE    def closeDocument(self, document):        l=self._docToViewMap[document][:]        for view in l:            if view.close(TRUE) == FALSE:                return FALSE        self.emit(PYSIGNAL("sigNumberOfDocsChanged"),())        return TRUE    def closeAllDocuments(self):        for document in self._docToViewMap.keys():            if not self.closeDocument(document):                raise DocumentsRemainingError()    </PRE><P>Getting rid of documents and views can      become quite complicated if you take into consideration all the      various methods available: a user can click on the close button      in the titlebar of the application, or in the view, or activate      the "close" <TTCLASS="CLASSNAME">QAction</TT>. In order to catch      the first possibility, we need to use event filters. Clicking on      the close button does not generate a signal we can connect to.      That being so, we should only call <TTCLASS="FUNCTION">close()</TT>      on the view, if we know that the closing has      <SPAN><ICLASS="EMPHASIS">not</I></SPAN> been initiated through the event filter      (otherwise we would fire the event filter again).</P><P>However, when the user selects "close      document" or "close all documents" from the menu or the toolbar,      <TTCLASS="FUNCTION">close()</TT> will not be automatically called on      the view &#8212; we have to do this ourselves. By looping      through all views in the document, and closing them, we will      generate an event: the event will be handled by the event      filter, which will call <TTCLASS="FUNCTION">closeView()</TT> for us.      And <TTCLASS="FUNCTION">closeView()</TT> will ask the user whether      it really wants to close the document if the view is the last      one.</P><P>It's an interesting exercise to follow      this happening with the BlackAdder debugger.</P></DIV><DIVCLASS="NAVFOOTER"><HRALIGN="LEFT"WIDTH="100%"><TABLESUMMARY="Footer navigation table"WIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top"><A accesskey="P" href="index.lxp@lxpwrap=x5339_252ehtm.htm">Prev</A></TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><A accesskey="H" href="index.lxp@lxpwrap=book1_252ehtm">Home</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top"><A accesskey="N" href="index.lxp@lxpwrap=x5451_252ehtm.htm">Next</A></TD></TR><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top">Document/View Manager</TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><A accesskey="U" href="index.lxp@lxpwrap=c5288_252ehtm.htm">Up</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top">Document</TD></TR></TABLE></DIV></BODY></HTML>      </td>      </tr>      </table>      </td>    </tr>  </table>      

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?