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

📄 index.lxp@lxpwrap=x7161_252ehtm.htm

📁 GUI Programming with Python
💻 HTM
📖 第 1 页 / 共 2 页
字号:
            self.removeFrom(widget)    def __compile(self, code):        try:            bytecode = compile(code,                               "&#60;string&#62;",                               "exec")            return bytecode        except Exception, e:            raise CompilationError(macroName, e)    def execute(self, out, err, globals, locals):        try:            oldstdout = sys.stdout            oldstderr = sys.stderr                        sys.stdout = out            sys.stderr = err            exec self.bytecode in globals            sys.stdout = oldstdout            sys.stderr = oldstderr        except Exception, e:            print e            print sys.exc_info            sys.stdout = oldstdout            sys.stderr = oldstderr            raise ExecutionError(e)      </PRE><P>By encapsulating each macro in a        <TTCLASS="CLASSNAME">QAction</TT>, it will become very easy to        assign shortcut keys, menu items and toolbar buttons to a        macro.</P><P>The <TTCLASS="CLASSNAME">MacroAction</TT>        class also takes care of compilation and execution. The        environment, consisting of the <TTCLASS="VARNAME">globals</TT> and        <TTCLASS="VARNAME">locals</TT> dictionaries, is passed in the        <TTCLASS="FUNCTION">execute()</TT> function. We also pass two        objects that replace the standard output and standard error        objects. These can be Kalam documents, for instance. Note how        we carefully restore the standard output and standard error        channels. The output of the print statement in the exception        clause will go to the redefined channel (in this instance, the        kalam document).</P><PRECLASS="PROGRAMLISTING">class MacroManager(QObject):    def __init__(self, parent = None, g = None, l = None, *args):        """ Creates an instance of the MacroManager.        Arguments:        g = dictionary that will be used for the global namespace        l = dictionary that will be used for the local namespace        """        apply(QObject.__init__,(self, parent,) + args)        self.macroObjects = {}        if g == None:            self.globals = globals()        else:            self.globals = g        if l == None:            self.locals = locals()        else:            self.locals = l      </PRE><P>All macros should be executed in the        same environment, which is why the macromanager can be        constructed with a <TTCLASS="VARNAME">globals</TT> and a        <TTCLASS="VARNAME">locals</TT> environment. This environment will        be used later to create a special API for the macro execution        environment, and it will include access to the window (i.e.        the <TTCLASS="CLASSNAME">KalamApp</TT> object) and to the        document objects (via the <TTCLASS="CLASSNAME">DocManager</TT>        object).</P><PRECLASS="PROGRAMLISTING">    def deleteMacro(self, macroName):        del self.macroObjects[macroName]    def addMacro(self, macroName, macroString):        action = MacroAction(macroString, self.parent())        self.macroObjects[macroName] = action        self.connect(action,                     PYSIGNAL("activated"),                     self.executeAction)        return action    def executeAction(self, action):        action.execute(sys.stdout,                       sys.stderr,                       self.globals,                       self.locals)      </PRE><P>The rest of the        <TTCLASS="CLASSNAME">MacroManager</TT> class is simple, including        methods to delete and add macros, and to execute a named        macro. Note how the <TTCLASS="VARNAME">activated</TT> signal of the        <TTCLASS="CLASSNAME">MacroAction</TT> is connected to the        <TTCLASS="FUNCTION">executeAction</TT> slot. This slot then calls        <TTCLASS="FUNCTION">execute()</TT> on the macro action with        standard output and standard error as default output channels.        A macro can, of course, create a new document and divert        output to that document.</P><P>The <TTCLASS="CLASSNAME">MacroManager</TT>        is instantiated as part of the startup process of the main        application:</P><PRECLASS="PROGRAMLISTING">    # kalamapp.py    def initMacroManager(self):        g=globals()        self.macroManager = MacroManager(self, g)      </PRE><P>Initializing the macromanager will also        entail deciding upon a good API for the macro extensions. This        will be covered in a later section.</P><P>Adapting the        <TTCLASS="FUNCTION">slotMacroExecuteDocument()</TT> slot function        to use the <TTCLASS="CLASSNAME">MacroManager</TT> is quite        straightforward:</P><PRECLASS="PROGRAMLISTING">    # kalamapp.py    def slotMacroExecuteDocument(self):        if self.docManager.activeDocument() == None:            QMessageBox.critical(self,                                 "Kalam",                                 "No document to execute as a macro ")            return        title = self.docManager.activeDocument().title()                try:            macroText = str(self.docManager.activeDocument().text())            self.macroManager.addMacro(title, macroText)        except CompilationError, e:            QMessageBox.critical(self,                                 "Kalam",                                 "Could not compile " +                                 self.docManager.activeDocument().title() +                                 "\n" + str(e))            return                try:            doc, view = self.docManager.createDocument(KalamDoc, KalamView)            doc.setTitle("Output of " + title)            self.macroManager.executeMacro(title, doc, doc)        except NoSuchMacroError, e:            QMessageBox.critical(self,                                 "Kalam",                                 "Error: could not find execution code.")        except ExecutionError, e:            QMessageBox.critical(self,                                 "Kalam",                                 "Error executing " + title +                                 "\n" + str(e))                    except Exception, e:            QMessageBox.critical(self,                                 "Kalam",                                 "Unpleasant error %s when trying to run %s." \                                 % (str(e), title))      </PRE><P>Note the careful handling of exceptions.        You don't want your application to crash or become unstable        because of a silly error in a macro.</P></DIV><DIVCLASS="SECT2"><H2CLASS="SECT2">startup macros</A></H2><P>Executing the contents of a document is        very powerful in itself&#8212;especially since we have access        to the complete <TTCLASS="CLASSNAME">KalamApp</TT> object, from        which we can reach the most outlying reaches of        <SPANCLASS="APPLICATION">Kalam</SPAN>.</P><P>It would be very unpleasant for a user        to have to load his macros as a document every time he wants        to execute a macro. Ideally, a user should be able to define a        set of macros that run at start-up, and be able to        add macros to menu options and the keyboard.</P><P>Solving the first problem takes care of        many other problems in one go. Users who are capable of        creating macros are probably able to create a startup macro        script that loads all their favorite macros.</P><P>We define two keys in the configuration        file, <TTCLASS="VARNAME">macrodir</TT> and        <TTCLASS="VARNAME">startupscript</TT>. These are the name and        location of the Python script that is executed when        <SPANCLASS="APPLICATION">Kalam</SPAN> is started. We start a user        macro after all standard initialization is complete:        </P><PRECLASS="PROGRAMLISTING"># kalamapp.py - fragment...class KalamApp(QMainWindow):    def __init__(self, *args):        apply(QMainWindow.__init__,(self, ) + args)        ...        # Run the startup macro script        self.runStartup()    ...    def runStartup(self):        """Run a Python script using the macro manager. Which script is        run is defined in the configuration variables macrodir and startup.        All output, and eventual failures are shown on the command-line.        """        try:            startupScript = os.path.join(kalamconfig.get("macrodir"),                                         kalamconfig.get("startupscript"))            startup = open(startupScript).read()            self.macroManager.addMacro("startup", startup)            self.macroManager.executeMacro("startup")        except Exception, e:            print "Could not execute startup macro", e        </PRE><P>A sample startup script might start      <SPANCLASS="APPLICATION">Kalam</SPAN> with an empty document:</P><PRECLASS="PROGRAMLISTING"># startup.py - startup script for Kalamprint "Kalam startup macro file"self.docManager.createDocument(KalamDoc, KalamView)      </PRE><P>It is already possible to do anything        you want using these macro extensions, but life can be made        easier by providing shortcut functions: a special macro API.        We will create one in the next section. However, a serious        macro writer would have to buy a copy of this book in order to        be able to use all functionality, because hiding the        underlying GUI toolkit would remove far too much power from        his hands. </P></DIV></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=c6996_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=x7295_252ehtm.htm">Next</A></TD></TR><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top">A Macro Language for <SPANCLASS="APPLICATION">Kalam</SPAN></TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><A accesskey="U" href="index.lxp@lxpwrap=c6996_252ehtm.htm">Up</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top">Creating a macro API from an application</TD></TR></TABLE></DIV></BODY></HTML>      </td>      </tr>      </table>      </td>    </tr>  </table>      

⌨️ 快捷键说明

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