index.lxp@lxpwrap=c4631_252ehtm.htm

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

HTM
794
字号
    <table border="0" cellspacing="0" cellpadding="3" width="100%"><tr><td>    <div align="center" id="bldcontent">      <a href="../default.htm"><img src="../images/opendocs.png" width="63" height="76" border="0"></a>      <br>      <div class="symbol">Your OpenSource Publisher&#153;</div>    </div>      </td></tr></table>    <div align="center" class="author">      	<a href="../products.lxp">Products</a>	&nbsp;|&nbsp;	<a href="../wheretobuy.lxp">Where to buy</a>	&nbsp;|&nbsp;	<a href="../bookstore.lxp">Retailers</a>	&nbsp;|&nbsp;	<a href="../faq.lxp">FAQ</a>	&nbsp;|&nbsp;        <a href="../writeforus.lxp">Write for Us.</a>        &nbsp;|&nbsp;        <a href="#contact">Contact Us.</a>  </div>    <table border="0" cellspacing="3" cellpadding="0" width="100%"><tr><td width="100%">      <div class="content">        <table border="0" cellspacing="2" cellpadding="0" width="100%"><tr><td width="100%">          <div align="center"><H4 CLASS="AUTHOR"><A NAME="AEN5">Boudewijn Rempt</A><br><a href="../../https@secure.linuxports.com/opendocs/default.htm"><img src=odpyqt125.png></a><br>ISBN: 0-97003300-4-4<br><a href="../../https@secure.linuxports.com/opendocs/default.htm">Available from bookstores everywhere or you can order it here.</a><p>You can download the source files for the book <a href="pyqtsrc.tgz">(code / eps) here.</a><hr></div>                    <HTML><HEAD><TITLE>Application Frameworks</TITLE><METANAME="GENERATOR"CONTENT="Modular DocBook HTML Stylesheet Version 1.72"><LINKREL="HOME"TITLE="GUI Programming with Python: QT Edition"HREF="book1.htm"><LINKREL="UP"TITLE="Creating real applications with PyQt"HREF="p4627.htm"><LINKREL="PREVIOUS"TITLE="Creating real applications with PyQt"HREF="p4627.htm"><LINKREL="NEXT"TITLE="Macro languages"HREF="x4760.htm"></HEAD><BODYCLASS="CHAPTER"BGCOLOR="#FFFFFF"TEXT="#000000"LINK="#0000FF"VLINK="#840084"ALINK="#0000FF"><DIVCLASS="NAVHEADER"><TABLESUMMARY="Header navigation table"WIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><THCOLSPAN="3"ALIGN="center">GUI Programming with Python: QT Edition</TH></TR><TR><TDWIDTH="10%"ALIGN="left"VALIGN="bottom"><A accesskey="P" href="index.lxp@lxpwrap=p4627_252ehtm.htm">Prev</A></TD><TDWIDTH="80%"ALIGN="center"VALIGN="bottom"></TD><TDWIDTH="10%"ALIGN="right"VALIGN="bottom"><A accesskey="N" href="index.lxp@lxpwrap=x4760_252ehtm.htm">Next</A></TD></TR></TABLE><HRALIGN="LEFT"WIDTH="100%"></DIV><DIVCLASS="CHAPTER"><H1>Chapter 12. Application Frameworks</A></H1><DIVCLASS="TOC"><DL><DT><B>Table of Contents</B></DT><DT><A href="index.lxp@lxpwrap=c4631_252ehtm.htm#AEN4637">Architecture: models, documents and views</A></DT><DT><A href="index.lxp@lxpwrap=x4760_252ehtm.htm">Macro languages</A></DT><DT><A href="index.lxp@lxpwrap=x4782_252ehtm.htm">Project layout</A></DT></DL></DIV><P>Up to this point we have seen only example    scripts&#8212; Exciting examples, illuminating examples, promising    examples, but still just examples. Example scripts are far removed    from the realities of a complex GUI application. For a complex    application you need a well thought-out modular structure, where    each component can find its place. You need an architecture, and    you need a design.</P><P>Most books on programming languages don't    progress much beyond basic examples; indeed, it is not really    possible to discuss a complete, complex application. Still, in    this part of the book I want to show how BlackAdder and PyQt can    help you achieve a well-written, maintainable application,    starting with the architecture, and then moving on to the outlines    of an application. On the way, I'll show you one useful way of    laying out the project structure. In the next few chapters we'll    build this framework into a real application.</P><DIVCLASS="SECT1"><H1CLASS="SECT1">Architecture: models, documents and views</A></H1><P>Let's start with the basics. Applications      are, essentially, interfaces that manipulate data. Whether you      are handling records from a database, an object tree from a      parsed HTML page, a game world, or a stream from a network      socket, there is always a reality that is mediated to the user      with an interface.</P><P>From this, it follows naturally that it      would be a good idea to separate bits of software that handle      the data from the interface. After all, you might want to      manipulate the same data with a different interface. In some      development environments this is quite difficult to achieve.      Visual Basic, for instance, almost mandates that you entangle      your data-mangling code with your GUI code. On the other side of      the scale, SmallTalk has explicit support for the most extended      form of the celebrated <SPAN><ICLASS="EMPHASIS">Observer</I></SPAN> pattern      &#8212; with the Model/View/Controller framework for the      SmallTalk user interface (or, in later versions, the      Model-View-Presenter architecture).</P><P>The component that represents the data is      variously termed <SPAN><ICLASS="EMPHASIS">model</I></SPAN> or      <SPAN><ICLASS="EMPHASIS">document</I></SPAN>; the component that actually shows      the data on screen is the <SPAN><ICLASS="EMPHASIS">view</I></SPAN>. The      model-view-controller framework adds a      <SPAN><ICLASS="EMPHASIS">controller</I></SPAN> component, which represents the      user input.</P><P>The controller component receives mouse      clicks, key press events and all other user input, and passes      those on to the model. The model determines its current state      from that input, and notifies the view that its representation      of the model should be changed. Sounds like PyQt signals and      slots would come in handy, doesn't it?</P><DIVCLASS="MEDIAOBJECT"><P><DIVCLASS="CAPTION"><P>Model-view-controller architecture</P></DIV></P></DIV><P>Be aware of the &#8216;fractal' nature of      this architecture. You can envision your entire application      divided into two or three parts &#8212; one component for the      model, one for the view, and perhaps one for the controller.      However, the same tripartition can be designed for the lowliest      checkbox class. Here, the boolean value is the model, the      picture of a box with a cross in it is the view, and the event      handler is the controller.</P><P>Swing, the Java gui toolkit, does exactly      this, and gives you the opportunity to write specialized models      and controllers for almost all its widgets (and specialized      views, too). PyQt doesn't go quite that far, and its widgets are      based on a simpler, more monolithic model. Like all good ideas      carried through to their extremes, writing models and      controllers for every widget is a bit tiresome. That's why      Java's Swing also presents capable default implementations for      the controller and model parts.</P><P>This chapter is about application      architecture, and when speaking of views and models, documents      and controllers, I do so only at the application architecture      level, not the widget level. However, a complex application      could consist of several models and views: for instance, in an      application based on a database, you could view every table as a      model and every corresponding form as a view.</P><DIVCLASS="SECT2"><H2CLASS="SECT2">A document-view framework</A></H2><P>The most basic architecture in which        application model and interface are separated is the        <SPAN><ICLASS="EMPHASIS">document-view</I></SPAN> paradigm. Here, you have        two basic modules: one representing your data (the document),        and one representing the interface that shows the data to the        user (the view). This architecture is prevalent in the Windows        world: the entire Microsoft MFC library is based on its        principles, and it is also popular in the Unix world, where        many KDE applications are based on it.</P><DIVCLASS="MEDIAOBJECT"><P><DIVCLASS="CAPTION"><P>The document-view architecture</P></DIV></P></DIV><P>There must be an interface between the        document and the view. Changes made in the view must be passed        on to the document, and vice-versa. A simple document-view        framework is readily constructed:</P><P>The basic application structure consists        of three classes: an application class, a view class and a        document class. In the next few chapters of this part, we'll        work with the framework to build a real application. We'll        also extend it to handle multiple document windows: the        framework detailed below can only work with one document. The        complete framework is in the file        <TTCLASS="FILENAME">docview.py</TT>.</P><DIVCLASS="EXAMPLE"></A><P><B>Example 12-1. A simple document-view framework</B></P><PRECLASS="PROGRAMLISTING">class DocviewDoc(QObject):    def __init__(self, *args):        apply(QObject.__init__, (self,)+args)        self.modified=FALSE    def slotModify(self):        self.modified = not self.modified        self.emit(PYSIGNAL("sigDocModified"),                  (self.modified,))    def isModified(self):        return self.modified        </PRE></DIV><P>You should always begin with designing        the application model - or so the theory goes. Your        preferences might lie with first creating a mock-up of the        interface using generic widgets, in order to be able to have        something concrete to talk about. That's fine with me. Anyway,        the <TTCLASS="CLASSNAME">DocviewDoc</TT> class represents the        <SPAN><ICLASS="EMPHASIS">document</I></SPAN> or the application model. This        can be as complex as you want. This class merely remembers        whether it has been modified. The controlling application can        query the document using the <TTCLASS="FUNCTION">isModified()</TT>        function to determine whether the document has changed, and it        can hook a <TTCLASS="CLASSNAME">QAction</TT> to the        <TTCLASS="FUNCTION">slotModify()</TT> slot to signal user        interaction to the model. Separating all code that handles the        application data makes it easy to write automated tests using        Pyunit. This is the topic of the next chapter.</P><P><TTCLASS="CLASSNAME">DocviewView</TT> is        the view class in the framework. A view is a visual component;        in PyQt it must somehow descend from        <TTCLASS="CLASSNAME">QWidget</TT> &#8212; either directly, as it        is done here, or via a more specialized class, such as        <TTCLASS="CLASSNAME">QTable</TT> or        <TTCLASS="CLASSNAME">QCanvas</TT>. A reference to the application        model is passed to the view. This breaks encapsulation        somewhat, but it makes initially setting up the display a lot        easier.</P><DIVCLASS="WARNING"><P></P><TABLECLASS="WARNING"BORDER="1"WIDTH="100%"><TR><TDALIGN="CENTER"><B>Warning</B></TD

⌨️ 快捷键说明

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