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

📄 index.lxp@lxpwrap=c1267_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>Signals and Slots in Depth</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="PyQt fundamentals"HREF="p1032.htm"><LINKREL="PREVIOUS"TITLE="Conclusion"HREF="x1263.htm"><LINKREL="NEXT"TITLE="Connecting with signals and slots"HREF="x1408.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=x1263_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=x1408_252ehtm.htm">Next</A></TD></TR></TABLE><HRALIGN="LEFT"WIDTH="100%"></DIV><DIVCLASS="CHAPTER"><H1>Chapter 7. Signals and Slots in Depth</A></H1><DIVCLASS="TOC"><DL><DT><B>Table of Contents</B></DT><DT><A href="index.lxp@lxpwrap=c1267_252ehtm.htm#AEN1273">The concept of signals and slots</A></DT><DT><A href="index.lxp@lxpwrap=x1408_252ehtm.htm">Connecting with signals and slots</A></DT><DT><A href="index.lxp@lxpwrap=x1631_252ehtm.htm">Disconnecting</A></DT><DT><A href="index.lxp@lxpwrap=x1807_252ehtm.htm">A parser-formatter using signals and slots</A></DT><DT><A href="index.lxp@lxpwrap=x2026_252ehtm.htm">Conclusion</A></DT></DL></DIV><P>The concept of signals and slots is possibly    the most interesting innovation in the Qt library. Good widgets    and a clean API are rare, but not unique. But until Qt appeared on    the horizon, connecting your widgets with your application and    your data was a nasty and error-prone endeavor &#8212; even in    Python. I will first discuss the problem that is solved by signals    and slots in some detail; then I will introduce the actual    mechanics of the signal/slot mechanism, and finish with an    application of the technique outside the GUI domain.</P><DIVCLASS="SECT1"><H1CLASS="SECT1">The concept of signals and slots</A></H1><P>The problem in a nutshell: imagine you have      an application, and the application shows a button on screen.      Whenever the button is pressed, you want a function in your      application to execute. Of course, you'd prefer that the button      doesn't know much about the application, or you would have to      write a different button for each application. In the next      example, the button has been coded to work only with an      application that has the      <TTCLASS="FUNCTION">doSomeApplicationSpecificFunction</TT> function.    </P><DIVCLASS="EXAMPLE"></A><P><B>Example 7-1. A stupid button which is not reusable</B></P><PRECLASS="PROGRAMLISTING">## stupid_button.py &#8212; this button is not reusable#class Button:    def __init__(self, application):      self.application = application    def clicked(self):        self.application.doSomeApplicationSpecificFunction()class Application:    def __init__(self):        self.button=Button(self)    def doSomeApplicationSpecificFunction(self):        print "Function called"app=Application()app.button.clicked() # simulate a user button press      </PRE></DIV><DIVCLASS="SECT2"><H2CLASS="SECT2">Callbacks</A></H2><P>This is no solution&#8212; the button code        isn't reusable at all. A better solution would be to pass the        <SPAN><ICLASS="EMPHASIS">function</I></SPAN> object to the button. Remember        that in Python functions are objects just like everything        else. In a language like C or C++ you would pass a        <SPAN><ICLASS="EMPHASIS">function pointer</I></SPAN>, the actual memory        address of the function being called. This is quite nasty,        because there is no way the compiler can check what arguments        are passed to the function represented by the function        pointer. In Python, passing functions around is really        easy.</P><DIVCLASS="EXAMPLE"></A><P><B>Example 7-2. A simple callback system</B></P><PRECLASS="PROGRAMLISTING">## callback.py &#8212; handing the function over the the app#class Button:    def __init__(self, function):        self.callbackFunction = function    def clicked(self):        apply(self.callbackFunction)class Application:    def __init__(self):        self.button=Button(self.doSomeApplicationSpecificFunction)    def doSomeApplicationSpecificFunction(self):        print "Function called"app=Application()app.button.clicked() # simulate a user button press        </PRE></DIV><DIVCLASS="NOTE"><BLOCKQUOTECLASS="NOTE"></A><P><B>Using <TTCLASS="FUNCTION">apply()</TT> to execute            function objects.: </B>Note the usage of the            <TTCLASS="FUNCTION">apply()</TT> function in the            <TTCLASS="FUNCTION">clicked()</TT> function &#8212; this            Python built-in function executes the function object you            pass as the first argument argument.  You can also hand it            parameters, as a tuple in the second argument to            <TTCLASS="FUNCTION">apply()</TT>. You'll see that idiom quite            often when we subclass Qt classes:</P><PRECLASS="PROGRAMLISTING">class MyWidget(QWidget):    def __init__(self, *args):        apply(QWidget.__init__, (self,) + args)        </PRE><P>This is useful because            <TTCLASS="CLASSNAME">QWidget</TT> and the other Qt classes            often have a lot of optional parameters, such as the            object name or certain widget flags. If we discount the            possibility that someone wants to use those optional            parameters, we would write:</P><PRECLASS="PROGRAMLISTING">class MyWidget(QWidget):    def __init__(self, parent):        QWidget.__init__(self, parent)          </PRE><P>This is far less flexible. In the previous example,            we created an argument tuple to be passed to the            <TTCLASS="FUNCTION">__init__()</TT> by first creating a tuple            containing our own object reference -            <TTCLASS="VARNAME">self</TT>, and then adding the arguments            from the variable positional argument list to that tuple.            Remember from the discussion of positional arguments in            <A href="index.lxp@lxpwrap=x719_252ehtm.htm#CH24POSITIONALARGUMENTS">the Section called <I>Methods and functions</I> in Chapter 4</A> that the            arguments in *args <SPAN><ICLASS="EMPHASIS">are</I></SPAN> a tuple, and            you can create a new tuple by adding two tuples.</P><P>In more recent versions of Python, you don't need to            use <TTCLASS="FUNCTION">apply()</TT> anymore to call the            constructor of a superclass with a variable number of            arguments. That is, from version 2.0 of Python you can            also use the following construction:</P><PRECLASS="SCREEN">&#62;&#62;&#62; class O(QObject):...     def __init__(self, *args):...             QObject.__init__(self, *args)... &#62;&#62;&#62; a=O()&#62;&#62;&#62; b=O(a, "bla")&#62;&#62;&#62; b&#60;__main__.O instance at 0x82b5c3c&#62;&#62;&#62;&#62; b.name()'bla'&#62;&#62;&#62; b.parent()&#60;__main__.O instance at 0x8106cb4&#62;&#62;&#62;&#62;       </PRE><P>That is, when calling the constructor of the            superclass, you can pass <TTCLASS="VARNAME">self</TT> as the            first argument, and then the argument list, with asterisks            and all.</P></BLOCKQUOTE></DIV></DIV><DIVCLASS="SECT2"><H2CLASS="SECT2">Action registry</A></H2><P>Unfortunately, this callback system is not        quite generic enough. For example, what if you wanted to        activate two functions when the button is pressed? While this        is not likely in the simple example, under more complex        situations it often occurs. Think of a text editor where        editing the text should change the internal representation of        the document, the word count in the statusbar, and the        edited-indicator in the titlebar. You wouldn't want to put all        this functionality in one function, but it is a natural fit        for signals and slots. You could have one signal,        <TTCLASS="FUNCTION">textChanged</TT>, that is connected to three        functions: <TTCLASS="FUNCTION">changeText()</TT>,        <TTCLASS="FUNCTION">setWordCount()</TT>,        <TTCLASS="FUNCTION">setEdited()</TT>.</P><P>Wouldn't it be extremely comfortable to        simply have a central registry where interested parties could        come together? Something like:</P><DIVCLASS="EXAMPLE"></A><P><B

⌨️ 快捷键说明

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