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 — 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 — 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 + -
显示快捷键?