⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 index.lxp@lxpwrap=x1807_252ehtm.htm

📁 GUI Programming with Python
💻 HTM
📖 第 1 页 / 共 2 页
字号:
    <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>A parser-formatter using signals and slots</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="Signals and Slots in Depth"HREF="c1267.htm"><LINKREL="PREVIOUS"TITLE="Disconnecting"HREF="x1631.htm"><LINKREL="NEXT"TITLE="Conclusion"HREF="x2026.htm"></HEAD><BODYCLASS="SECT1"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=x1631_252ehtm.htm">Prev</A></TD><TDWIDTH="80%"ALIGN="center"VALIGN="bottom">Chapter 7. Signals and Slots in Depth</TD><TDWIDTH="10%"ALIGN="right"VALIGN="bottom"><A accesskey="N" href="index.lxp@lxpwrap=x2026_252ehtm.htm">Next</A></TD></TR></TABLE><HRALIGN="LEFT"WIDTH="100%"></DIV><DIVCLASS="SECT1"><H1CLASS="SECT1">A parser-formatter using signals and slots</A></H1><P>The use of signals and slots in the      previous section was an example of using signals and slots in      GUI building. Of course, you can use signals and slots to link      GUI widgets with each other, and most of your slot      implementations will be in subclasses of      <TTCLASS="CLASSNAME">QWidget</TT> &#8212; but the mechanism works      well under other circumstances. A GUI is not necessary.</P><P>In this section, I will show how signals      and slots make a natural extension to the event driven nature of      XML parsers. As you probably know, XML is a fairly simple      mark-up language that can be used to represent hierarchical      data. There are basically two ways to look at XML data. One is      to convert the data in one fell swoop into some hierarchical      representation (for example, dictionaries containing      dictionaries). This method is the DOM (data-object-model)      representation. Alternatively, you can parse the data character      by character, generating an event every time a certain chunk has      been completed; this is the SAX parser model.</P><P>Python contains support for both XML      handling models in its standard libraries. The currently      appreciated module is xml.sax, which can make use of the fast      expat parser. However, expat is not part of standard Python.      There is an older, deprecated module, xmllib, which uses regular      expressions for parsing. While deprecated, this module is still      the most convenient introduction to XML handling with Python.      It's also far more &#8216;Pythonic' in feel than the Sax module,      which is based on the way Java does things.    </P><P>We'll create a special module that will use      xmllib to parse an XML document and generate PyQt signals for      all elements of that document. It is easy to connect these      signals to another object (for instance, a PyQt      <TTCLASS="CLASSNAME">QListView</TT> which can show the XML document      in a treeview). But it would be just as easy to create a      formatter object that would present the data as HTML. A slightly      more complicated task would be to create a formatter object that      would apply XSLT transformations to the XML document &#8212;      that is, it would format the XML using stylesheets. Using      signals and slots, you can connect more than one transformation      to the same run of the parser. A good example would be a      combination of a GUI interface, a validator, and a statistics      calculator.</P><P>The next example is very simple. It is easy to extend,    though, with special nodes for comments, a warning message    box for errors, and more columns for attributes.</P><DIVCLASS="EXAMPLE"></A><P><B>Example 7-9. An XML parser with signals and slots</B></P><PRECLASS="PROGRAMLISTING">## qtparser.py &#8212; a simple parser that, using xmllib,# generates a signal for every parsed XML document.#import sysimport xmllib                                              <IMGSRC="images/callouts/1.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(1)"></A>from qt import *TRUE=1                                                     <IMGSRC="images/callouts/2.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(2)"></A>FALSE=0        </PRE><DIVCLASS="CALLOUTLIST"><DLCOMPACT="COMPACT"><DT><A href="index.lxp@lxpwrap=x1807_252ehtm.htm#XMLLIB"><IMGSRC="images/callouts/1.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(1)"></A></DT><DD>We import the deprecated              xmllib module. It is deprecated because the sax module,              which uses the expat library, is a lot faster.              The xmllib module is far easier to use, however, and since it              uses regular expressions for its parsing, it is              available everywhere, while the expat library must be              compiled separately.</DD><DT><A href="index.lxp@lxpwrap=x1807_252ehtm.htm#TRUE"><IMGSRC="images/callouts/2.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(2)"></A></DT><DD>It is often convenient to          define constants for the boolean values true and false.</DD></DL></DIV><PRECLASS="PROGRAMLISTING">class Parser(xmllib.XMLParser):                            <IMGSRC="images/callouts/1.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(1)"></A>    def __init__(self, qObject,  *args):                   <IMGSRC="images/callouts/2.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(2)"></A>        xmllib.XMLParser.__init__(self)        self.qObject=qObject    def start(self, document):                             <IMGSRC="images/callouts/3.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(3)"></A>        xmllib.XMLParser.feed(self, document)        xmllib.XMLParser.close(self)        </PRE><DIVCLASS="CALLOUTLIST"><DLCOMPACT="COMPACT"><DT><A href="index.lxp@lxpwrap=x1807_252ehtm.htm#CLASS"><IMGSRC="images/callouts/1.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(1)"></A></DT><DD>This is the <TTCLASS="CLASSNAME">Parser</TT> class. It              inherits the <TTCLASS="CLASSNAME">XMLParser</TT> class from              the xmllib module. The <TTCLASS="CLASSNAME">XMLParser</TT>              class can be used in two ways: by overriding a set of              special methods that are called when the parser              encounters a certain kind of XML element, or by              overriding a variable, <TTCLASS="VARNAME">self.elements</TT>,              which refers to a dictionary of tag-to-method mappings.              Overriding <TTCLASS="VARNAME">self.elements</TT> is very              helpful if you are writing a parser for a certain DTD or              XML document type definition, though it is not the way              to go for a generic XML structure viewer (such as the              one we are making now).</DD><DD><P>An example for a Designer ui file could contain the          following definition:</P></DD><PRECLASS="PROGRAMLISTING">self.elements={'widget'  : (self.start_widget,                            self.end_widget)              ,'class'   : (self.start_class,                            self.end_class)              ,'property': (self.start_property,                            self.end_property)              ,name'     : (self.start_name,                            self.end_name)}          </PRE><DD><P>The keys to this dictionary are the actual tag              strings. The tuple that follows the key consists of the              functions that should be called for the opening and the              ending tag. If you don't want a function to be called,              enter None. Of course, you must implement these              functions yourself, in the derived parser class.</P></DD><DT><A href="index.lxp@lxpwrap=x1807_252ehtm.htm#CONSTRUCTOR"><IMGSRC="images/callouts/2.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(2)"></A></DT><DD>The first argument (after self, of course) to the              constructor is a QObject. Multiple inheritance isn't a              problem in Python, generally speaking, but you cannot              multiply inherit from PyQt classes. Sip gets hopelessly              confused if you do so. So we pass a              <TTCLASS="CLASSNAME">QObject</TT> to the constructor of the              <TTCLASS="CLASSNAME">Parser</TT> class. Later, we will have              this <TTCLASS="CLASSNAME">QObject</TT> object emit the              necessary signals.</DD><DT><A href="index.lxp@lxpwrap=x1807_252ehtm.htm#START"><IMGSRC="images/callouts/3.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(3)"></A></DT><DD>The <TTCLASS="FUNCTION">start</TT>            function takes a string as its parameter. This string            should contain the entire XML document. It is            also possible to rewrite this function to read a file line by            line; the default approach makes it difficult to work with            really large XML files. Reading a file line by line is a            lot easier on your computer's memory. You should call            <TTCLASS="FUNCTION">close()</TT> after the last bit of text            has been passed to the parser.</DD></DL></DIV><PRECLASS="PROGRAMLISTING">    #    # Data handling functions                              <IMGSRC="images/callouts/1.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(1)"></A>    #    def handle_xml(self, encoding, standalone):            <IMGSRC="images/callouts/2.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(2)"></A>        self.qObject.emit(PYSIGNAL("sigXML"),                          (encoding, standalone))                                                           <IMGSRC="images/callouts/3.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(3)"></A>    def handle_doctype(self, tag, pubid, syslit, data):        self.qObject.emit(PYSIGNAL("sigDocType"),                         (tag, pubid, syslit, data,))      <IMGSRC="images/callouts/4.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(4)"></A>    def handle_data(self, data):        self.qObject.emit(PYSIGNAL("sigData"),(data,))     <IMGSRC="images/callouts/5.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(5)"></A>    def handle_charref(self, ref):        self.qObject.emit(PYSIGNAL("sigCharref"),(ref,))   <IMGSRC="images/callouts/6.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(6)"></A>    def handle_comment(self, comment):        self.qObject.emit(PYSIGNAL("sigComment"),(comment,))<IMGSRC="images/callouts/7.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(7)"></A>    def handle_cdata(self, data):        self.qObject.emit(PYSIGNAL("sigCData"),(data,))    <IMGSRC="images/callouts/8.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(8)"></A>    def handle_proc(self, data):        self.qObject.emit(PYSIGNAL("sigProcessingInstruction"),<IMGSRC="images/callouts/9.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(9)"></A>                         (data,))    def handle_special(self, data):                        <IMGSRC="images/callouts/10.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(10)"></A>        self.qObject.emit(PYSIGNAL("sigSpecial"), (data,))    def syntax_error(self, message):                       <B>(11)</B></A>        self.qObject.emit(PYSIGNAL("sigError"),(message,))    def unknown_starttag(self, tag, attributes):           <B>(12)</B></A>        self.qObject.emit(PYSIGNAL("sigStartTag"),                         (tag,attributes))                                                           <B>(13)</B></A>    def unknown_endtag(self, tag):        self.qObject.emit(PYSIGNAL("sigEndTag"),(tag,))                                                           <B>(14)</B></A>    def unknown_charref(self, ref):        self.qObject.emit(PYSIGNAL("sigCharRef"),(ref,))    def unknown_entityref(self, ref):        self.qObject.emit(PYSIGNAL("sigEntityRef"),(ref,))        </PRE><DIVCLASS="CALLOUTLIST"><DLCOMPACT="COMPACT"><DT><A href="index.lxp@lxpwrap=x1807_252ehtm.htm#DATA-HANDLING"><IMGSRC="images/callouts/1.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(1)"></A></DT><DD>The              xmllib.<TTCLASS="CLASSNAME">XMLParser</TT> class defines a              number of methods that should be overridden if you want              special behavior. Even though we will only use the              methods that are called when a document is started and              when a simple element is opened and closed, I've              implemented all possible functions here.</DD><DT><A href="index.lxp@lxpwrap=x1807_252ehtm.htm#DH1"><IMGSRC="images/callouts/2.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(2)"></A></DT><DD>Every valid XML document should              start with a magic text that declares itself to be XML              &#8212; note that that the .ui Designer files don't              comply with this requirement. This method is fired (and              thus the signal is fired) when the parser encounters              this declaration. Normally, it looks like this:              <TTCLASS="LITERAL">&#60;?xml version="1.0"                standalone="no"?&#62;</TT>, with the minor              variation that standalone can also have the value "yes".          </DD><DT><A href="index.lxp@lxpwrap=x1807_252ehtm.htm#DH2"><IMGSRC="images/callouts/3.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(3)"></A></DT><DD>If an XML document has a              documenttype, this method is called. A doctype              declaration looks like this:</DD><PRECLASS="SCREEN">&#60;!DOCTYPE book PUBLIC "-//Norman Walsh//DTD DocBk XML V3.1.4//EN"     "http://nwalsh.com/docbook/xml/3.1.4/db3xml.dtd"&#62;            </PRE><DD><P>and points to a DTD &#8212; a              description of what's allowed in this particular kind of              XML document.          </P></DD><DT><A href="index.lxp@lxpwrap=x1807_252ehtm.htm#DH3"><IMGSRC="images/callouts/4.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(4)"></A></DT><DD>There can be data in between the tags in an XML document,            just as with the text in a HTML document. This function is            called when the parser encounters such data.</DD><DT><A href="index.lxp@lxpwrap=x1807_252ehtm.htm#DH4"><IMGSRC="images/callouts/5.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(5)"></A></DT><DD>In XML, you can use special              characters that are entered with  &#38;#, a number, and              closed with a semicolon. Python's xmllib will want to              translate this to an ASCII character. You cannot use

⌨️ 快捷键说明

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