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

📄 index.lxp@lxpwrap=x7161_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>Integrating macros with a GUI</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="A Macro Language for Kalam"HREF="c6996.htm"><LINKREL="PREVIOUS"TITLE="A Macro Language for Kalam"HREF="c6996.htm"><LINKREL="NEXT"TITLE="Creating a macro API from an application"HREF="x7295.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=c6996_252ehtm.htm">Prev</A></TD><TDWIDTH="80%"ALIGN="center"VALIGN="bottom">Chapter 20. A Macro Language for <SPANCLASS="APPLICATION">Kalam</SPAN></TD><TDWIDTH="10%"ALIGN="right"VALIGN="bottom"><A accesskey="N" href="index.lxp@lxpwrap=x7295_252ehtm.htm">Next</A></TD></TR></TABLE><HRALIGN="LEFT"WIDTH="100%"></DIV><DIVCLASS="SECT1"><H1CLASS="SECT1">Integrating macros with a GUI</A></H1><P>Before we can start defining what we allow      our users to do to <SPANCLASS="APPLICATION">Kalam</SPAN>, we need to      build the core macro execution functionality. The first step is      to make sure users can execute the contents of a      document.</P><DIVCLASS="SECT2"><H2CLASS="SECT2">Executing the contents of a document</A></H2><P>Unless you have skipped all previous        occasions of creating and adding an action to the menubar and        the toolbar, you will know by now how to do so. I have        supplied the slot code that executes the contents of the        currently active document. You will find the complete code in        the <TTCLASS="FILENAME">kalamapp.py</TT> file that belongs to this        chapter.</P><PRECLASS="PROGRAMLISTING"># kalamapp.py...class KalamApp(QMainWindow):...    # Macro slots...    def slotMacroExecuteDocument(self):        if self.docManager.activeDocument() == None:            QMessageBox.critical(self,                                 "Kalam",                                 "No document to execute as a macro ")            return        try:            bytecode = compile(str(self.docManager.activeDocument().text()),                               "&#60;string&#62;",                               "exec")        except Exception, e:            QMessageBox.critical(self,                                 "Kalam",                                 "Could not compile " +                                 self.docManager.activeDocument().title() +                                 "\n" + str(e))        try:            exec bytecode # Note: we don't yet have a separate namespace                          # for macro execution        except Exception, e:            QMessageBox.critical(self,                                 "Kalam",                                 "Error executing " +                                 self.docManager.activeDocument().title() +                                 "\n" + str(e))...      </PRE><P>We are being a bit careful here, and        thus compile the code first to check for syntax errors. These,        along with execution errors, will be shown in a dialog box.        Note that anything you print from here will go to standard        output&#8212;that is, a black hole if you run        <SPANCLASS="APPLICATION">Kalam</SPAN> by activating an icon, or the        terminal window if you run <SPANCLASS="APPLICATION">Kalam</SPAN>        from the shell prompt. It would be a logical step to redirect        any output to a fresh <TTCLASS="CLASSNAME">Kalam</TT> document        (this is what <SPANCLASS="APPLICATION">Emacs</SPAN> does). It is        quite easy to achieve. You can reassign the standard and error        output channels to any object you want, as long as it has a        <TTCLASS="FUNCTION">write()</TT> function that accepts a string.        We might want to add a <TTCLASS="FUNCTION">write()</TT> function        to <TTCLASS="CLASSNAME">KalamDoc</TT>.</P><P>The implementation of        <TTCLASS="FUNCTION">write()</TT> in        <TTCLASS="CLASSNAME">KalamDoc</TT> is very simple:</P><PRECLASS="PROGRAMLISTING"># kalamdoc.py - fragment...    def write(self, text, view = None):        self.text().append(text)        self.emit(PYSIGNAL("sigDocTextChanged"),                  (self._text, view))      </PRE><P>Having done that, redirecting all output        is easy:</P><PRECLASS="PROGRAMLISTING">        ...    def slotMacroExecuteDocument(self):        ...            import sys            document = self.docManager.createDocument(KalamDoc, KalamView)            document.setTitle("Output of " + title)            oldstdout = sys.stdout            oldstderr = sys.stderr            sys.stdout = document            sys.stderr = document            exec bytecode # Note: we don't yet have a separate namespace                          # for macro execution            sys.stdout = oldstdout            sys.stderr = oldstderr        ...      </PRE><P>It is necessary to save the "real"        standard output and standard error channels in order to be        able to restore them when we are done printing to the output        document. Otherwise all output, from anywhere inside Kalam,        would go forever to that document, with nasty consequences if        the user were to remove the document.</P><P>Until we create a namespace specially        for executing macros, everything runs locally to the function        that executes the macro. That is, you can use        <TTCLASS="VARNAME">self</TT> to refer to the current instance of        <TTCLASS="CLASSNAME">KalamApp</TT>.</P><DIVCLASS="MEDIAOBJECT"><P><DIVCLASS="CAPTION"><P>Executing a bit of code from a            document.</P></DIV></P></DIV><P>Of course, littering the        <TTCLASS="CLASSNAME">KalamApp</TT> with macro execution code        isn't the best of ideas. This leads us to the creation of a        macro manager class, <TTCLASS="CLASSNAME">MacroManager</TT>,        which keeps a dictionary of compiled code objects that can be        executed at will. I won't show the unit tests here: it is        available with the full source code.</P><PRECLASS="PROGRAMLISTING">"""macromanager.py - manager class for macro administration and executioncopyright: (C) 2001, Boudewijn Remptemail:     boud@rempt.xs4all.nl"""from qt import *import sysclass MacroError(Exception):passclass NoSuchMacroError(MacroError):    def __init__(self, macro):        ERR = "Macro %s is not installed"        self.errorMessage = ERR % (macro)    def __repr__(self):        return self.errorMessage    def __str__(self):        return self.errorMessageclass CompilationError(MacroError):    def __init__(self, macro, error):        ERR = "Macro %s could not be compiled. Reason: %s"        self.errorMessage = ERR % (macro, str(error))        self.compilationError = error    def __repr__(self):        return self.errorMessage    def __str__(self):        return self.errorMessageclass ExecutionError(MacroError):    def __init__(self, error):        ERR = "Macro could not be executed. Reason: %s"        self.errorMessage = ERR % (str(error))        self.executionError = error    def __repr__(self):        return self.errorMessage    def __str__(self):        return self.errorMessage      </PRE><P>First, a couple of exceptions are        defined. We want to separate the GUI handling of problems with        the macro from the actual execution, so that whenever        something goes wrong, an exception is thrown.</P><PRECLASS="PROGRAMLISTING">class MacroAction(QAction):    def __init__(self, code, *args):        apply(QAction.__init__,(self,) + args)        self.code = code        self.bytecode = self.__compile(code)        self.locations=[]        self.connect(self,                     SIGNAL("activated()"),                     self.activated)    def activated(self):        self.emit(PYSIGNAL("activated"),(self,))    def addTo(self, widget):        apply(QAction.addTo,(self, widget))        self.locations.append(widget)    def removeFrom(self, widget):        QAction.removeFrom(self, widget)        del self.locations[widget]    def remove(self):        for widget in self.locations:

⌨️ 快捷键说明

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