index.lxp@lxpwrap=x1631_252ehtm.htm

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

HTM
1,001
字号
VSPACE="0"BORDER="0"ALT="(4)"></A>    def timerEvent(self, ev):                              <IMGSRC="images/callouts/5.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(5)"></A>        self.emit(PYSIGNAL("timeSignal"), (self.dataFunction(),))<IMGSRC="images/callouts/6.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(6)"></A>        </PRE><DIVCLASS="CALLOUTLIST"><DLCOMPACT="COMPACT"><DT><A href="index.lxp@lxpwrap=x1631_252ehtm.htm#D1"><IMGSRC="images/callouts/1.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(1)"></A></DT><DD>The              <TTCLASS="CLASSNAME">DataSource</TT> class is a generic              datasource. We base it on <TTCLASS="CLASSNAME">QObject</TT>              so we can emit signals from it.</DD><DT><A href="index.lxp@lxpwrap=x1631_252ehtm.htm#D2"><IMGSRC="images/callouts/2.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(2)"></A></DT><DD>The constructor of              <TTCLASS="CLASSNAME">DataSource</TT> takes a function as              the first parameter. This is the actual dataproducing              function. We saw their definitions above. Remember,              every function is an object in its own right &#8212; you can              pass them on as arguments, add them to object              dictionaries, etc.</DD><DT><A href="index.lxp@lxpwrap=x1631_252ehtm.htm#D3"><IMGSRC="images/callouts/3.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(3)"></A></DT><DD>Every second (1000              milliseconds) the timer will generate an event that              will be caught by the <TTCLASS="FUNCTION">timerEvent</TT>              function.</DD><DT><A href="index.lxp@lxpwrap=x1631_252ehtm.htm#D4"><IMGSRC="images/callouts/4.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(4)"></A></DT><DD>By creating a local name that              links to the passed function object, we can call this              function as if it were a plain member function of the              class.</DD><DT><A href="index.lxp@lxpwrap=x1631_252ehtm.htm#D5"><IMGSRC="images/callouts/5.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(5)"></A></DT><DD>The              <TTCLASS="FUNCTION">timerEvent</TT> is called every second              because of the events generated by the timer              object.</DD><DT><A href="index.lxp@lxpwrap=x1631_252ehtm.htm#D6"><IMGSRC="images/callouts/6.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(6)"></A></DT><DD>A Python signal is emitted, of              the name "timeSignal" which passes the result of the              <TTCLASS="FUNCTION">dataFunction</TT> on.</DD></DL></DIV><PRECLASS="PROGRAMLISTING">class DataWindow(frmDataSource):                           <IMGSRC="images/callouts/1.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(1)"></A>    def __init__(self, *args):        apply(frmDataSource.__init__, (self,) + args)        self.sources = {                                   <IMGSRC="images/callouts/2.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(2)"></A>            "random" : DataSource(randomFunction),            "time" : DataSource(timeFunction),            "cookies" : DataSource(cookieFunction)            }        self.cmbSource.insertStrList(self.sources.keys())  <IMGSRC="images/callouts/3.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(3)"></A>        self.currentSource=self.sources.keys()[0]          <IMGSRC="images/callouts/4.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(4)"></A>        self.connect(self.sources[self.currentSource],     <IMGSRC="images/callouts/5.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(5)"></A>                     PYSIGNAL("timeSignal"),                     self.appendData)                         def switchDataSource(self, source):                    <IMGSRC="images/callouts/6.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(6)"></A>        source=str(source)                                 <IMGSRC="images/callouts/7.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(7)"></A>        self.disconnect(self.sources[self.currentSource],  <IMGSRC="images/callouts/8.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(8)"></A>                     PYSIGNAL("timeSignal"),                     self.appendData)        self.connect(self.sources[source],                 <IMGSRC="images/callouts/9.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(9)"></A>                     PYSIGNAL("timeSignal"),                     self.appendData)        self.currentSource=source            def appendData(self, value):                           <IMGSRC="images/callouts/10.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(10)"></A>        self.mleWindow.insertLine(value)        self.mleWindow.setCursorPosition(self.mleWindow.numLines(), 0)        </PRE><DIVCLASS="CALLOUTLIST"><DLCOMPACT="COMPACT"><DT><A href="index.lxp@lxpwrap=x1631_252ehtm.htm#DW1"><IMGSRC="images/callouts/1.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(1)"></A></DT><DD>The <TTCLASS="CLASSNAME">DataWindow</TT> class is a              subclass of the generated form &#8212; class              <TTCLASS="CLASSNAME">frmDataSource</TT>.            </DD><DT><A href="index.lxp@lxpwrap=x1631_252ehtm.htm#DW2"><IMGSRC="images/callouts/2.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(2)"></A></DT><DD>We create a Python dictionary, which takes              <TTCLASS="CLASSNAME">DataSource</TT> objects (each              instantiated with a different data generating function)              and maps them to distinct names.</DD><DT><A href="index.lxp@lxpwrap=x1631_252ehtm.htm#DW3"><IMGSRC="images/callouts/3.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(3)"></A></DT><DD>The <TTCLASS="VARNAME">self.cmbSource</TT> combobox is              defined in the generated form. We fill the combobox with              the set of keys to the dictionary. To do this, we use              <TTCLASS="FUNCTION">InsertStrList</TT> and not              <TTCLASS="FUNCTION">InsertStringList</TT>. A list of Python              strings is converted automatically to a              <TTCLASS="CLASSNAME">QStrList</TT>, while a              <TTCLASS="CLASSNAME">QStringList</TT> object must be constructed              separately.</DD><DT><A href="index.lxp@lxpwrap=x1631_252ehtm.htm#DW4"><IMGSRC="images/callouts/4.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(4)"></A></DT><DD><TTCLASS="VARNAME">self.currentSource</TT> is a local            variable where we keep track of what datasource we're            looking at.</DD><DT><A href="index.lxp@lxpwrap=x1631_252ehtm.htm#DW5"><IMGSRC="images/callouts/5.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(5)"></A></DT><DD>Simply connect the "timeSignal" Python signal from            one of the objects in the dictionary of datasources to the            slot that will display the output.</DD><DT><A href="index.lxp@lxpwrap=x1631_252ehtm.htm#DW6"><IMGSRC="images/callouts/6.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(6)"></A></DT><DD>The <TTCLASS="FUNCTION">switchDataSource</TT> function              is where interesting things happen. This function is              a slot that is called whenever the user selects              something from the combobox. The              <TTCLASS="FUNCTION">clicked()</TT> signal of the              combobox was connected to the              <TTCLASS="FUNCTION">switchDataSource</TT> slot              of the Designer.            </DD><DT><A href="index.lxp@lxpwrap=x1631_252ehtm.htm#DW7"><IMGSRC="images/callouts/7.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(7)"></A></DT><DD>The variable passed by the signal              connected to this slot is of the              <TTCLASS="CLASSNAME">QString</TT> type. The index to              the dictionary of data sources is a Python string. This              is one instance where we <SPAN><ICLASS="EMPHASIS">must</I></SPAN>              convert a <TTCLASS="CLASSNAME">QString</TT> to a Python              string.</DD><DT><A href="index.lxp@lxpwrap=x1631_252ehtm.htm#DW8"><IMGSRC="images/callouts/8.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(8)"></A></DT><DD>Using the cached current datasource, we disconnect              the signals it generates from the              <TTCLASS="FUNCTION">appendData</TT> function.</DD><DT><A href="index.lxp@lxpwrap=x1631_252ehtm.htm#DW9"><IMGSRC="images/callouts/9.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(9)"></A></DT><DD>After the signal is disconnected, we can create a            new connection.</DD><DT><A href="index.lxp@lxpwrap=x1631_252ehtm.htm#DW10"><IMGSRC="images/callouts/10.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(10)"></A></DT><DD>This is the function that shows the data. It simply            adds every value that is passed on by the signal to the            multi-line edit widget, and then sets the cursor to the            last line. If this is not done, the display will not follow            the added data, and instead stay at the beginning.</DD></DL></DIV><PRECLASS="PROGRAMLISTING">def main(args):    a = QApplication(args)    QObject.connect(a,SIGNAL('lastWindowClosed()'),a,SLOT('quit()'))    w = DataWindow()    a.setMainWidget(w)    w.show()    a.exec_loop()if __name__ == '__main__':    main(sys.argv)        </PRE></DIV><P>As you can see, connecting and      disconnecting signals and slots is a natural and intuitive      technique. Their use is not limited to connecting GUI widgets,      as signals and slots are also useful for the separation of the      data model of an application from its interface. In Part III, We      will investigate an application model based on the strict      separation of model and interface, using signals and slots to      tie everything together.</P></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=x1408_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=x1807_252ehtm.htm">Next</A></TD></TR><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top">Connecting with signals and slots</TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><A accesskey="U" href="index.lxp@lxpwrap=c1267_252ehtm.htm">Up</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top">A parser-formatter using signals and slots</TD></TR></TABLE></DIV></BODY></HTML>      </td>      </tr>      </table>      </td>    </tr>  </table>      

⌨️ 快捷键说明

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