index.lxp@lxpwrap=x1631_252ehtm.htm
来自「GUI Programming with Python」· HTM 代码 · 共 1,001 行 · 第 1/2 页
HTM
1,001 行
<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™</div> </div> </td></tr></table> <div align="center" class="author"> <a href="../products.lxp">Products</a> | <a href="../wheretobuy.lxp">Where to buy</a> | <a href="../bookstore.lxp">Retailers</a> | <a href="../faq.lxp">FAQ</a> | <a href="../writeforus.lxp">Write for Us.</a> | <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>Disconnecting</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="Signals and Slots in Depth"HREF="c1267.htm"><LINKREL="PREVIOUS"TITLE="Connecting with signals and slots"HREF="x1408.htm"><LINKREL="NEXT"TITLE="A parser-formatter using signals and slots"HREF="x1807.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=x1408_252ehtm.htm">Prev</A></TD><TDWIDTH="80%"ALIGN="center"VALIGN="bottom">Chapter 7. Signals and Slots in Depth</TD><TDWIDTH="10%"ALIGN="right"VALIGN="bottom"><A accesskey="N" href="index.lxp@lxpwrap=x1807_252ehtm.htm">Next</A></TD></TR></TABLE><HRALIGN="LEFT"WIDTH="100%"></DIV><DIVCLASS="SECT1"><H1CLASS="SECT1">Disconnecting</A></H1><P>What can be bound, can be severed, and even for signals and slots there are divorce courts. You can disconnect a signal from a slot using <TTCLASS="CLASSNAME">QObject</TT>.<TTCLASS="FUNCTION">disconnect()</TT>. Why would you want to disconnect signals? Not preparatory to removing a connected widget, for the connections are severed automatically when the signal recipient is deleted. I've never needed <TTCLASS="FUNCTION">disconnect()</TT> myself, but with a bit of imagination, a likely scenario can be found.</P><P>Imagine therefore that you are writing a monitoring application. There are several data sources, but you want only to look at one at a time. The data keeps flowing in from a host of objects representing the sources. This is a scenario well worth writing a small test for...</P><P>First, we design the interface using BlackAdder's designer module or Qt Designer. This is a simple affair, with a combobox that contains the datasources, a read-only multi-line edit control that will show the output of the selected datasource, and a close button. The dialog window will be the main window, too.</P><DIVCLASS="MEDIAOBJECT"><P><DIVCLASS="CAPTION"><P>Designing the interface</P></DIV></P></DIV><P>Then, we use Designer to add an extra slot to the form, <TTCLASS="FUNCTION">switchDataSource</TT>, which will be called whenever a new item is selected in the datasource combobox. Drawing a simple line from the combobox to the form gives us the opportunity to connect signal and slot:</P><DIVCLASS="MEDIAOBJECT"><P><DIVCLASS="CAPTION"><P>Connecting the <TTCLASS="FUNCTION">activated(const QString&)</TT> signal to the <TTCLASS="FUNCTION">switchDataSource()</TT> slot.</P></DIV></P></DIV><P>This raises an interesting point. If the <TTCLASS="FUNCTION">activated(const QString&)</TT> signal passes a <TTCLASS="CLASSNAME">QString</TT> to the slot, shouldn't we define the slot <TTCLASS="FUNCTION">switchDataSource()</TT> in the Designer as having an argument?</P><P>The answer is no— we will subclass the generated python code, and in the subclass we will override the generated slot with a function that has the requisite number of arguments. Python does not know the concept of overloading, so all functions with the same name are the same function. It is actually impossible to define the number of arguments a slot has in the Designer— you can only match signals to slots without arguments.</P><P>Having designed the form, we can generate it with a single menu-choice and start subclassing it, adding all kinds of interesting bits. First, we create the actual datasources.</P><DIVCLASS="EXAMPLE"></A><P><B>Example 7-8. datasource.py — connecting and disconnecting signals and slots</B></P><PRECLASS="PROGRAMLISTING">## datasource.py — a monitor for different datasources#import sys, whrandom <IMGSRC="images/callouts/1.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(1)"></A>from time import * <IMGSRC="images/callouts/2.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(2)"></A>from qt import *from frmdatasource import frmDataSource <IMGSRC="images/callouts/3.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(3)"></A> </PRE><DIVCLASS="CALLOUTLIST"><DLCOMPACT="COMPACT"><DT><A href="index.lxp@lxpwrap=x1631_252ehtm.htm#I1"><IMGSRC="images/callouts/1.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(1)"></A></DT><DD>The sys module is needed for QApplication; whrandom is one of the two random modules Python provides.</DD><DT><A href="index.lxp@lxpwrap=x1631_252ehtm.htm#I2"><IMGSRC="images/callouts/2.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(2)"></A></DT><DD>The time module provides lots of time related functions.</DD><DT><A href="index.lxp@lxpwrap=x1631_252ehtm.htm#I3"><IMGSRC="images/callouts/3.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(3)"></A></DT><DD>This is the form we designed and generated with BlackAdder.</DD></DL></DIV><PRECLASS="PROGRAMLISTING">COOKIES=["""That is for every schoolboy and schoolgirl for the next<IMGSRC="images/callouts/1.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(1)"></A>four hundred years. Have you any idea how much suffering you are goingto cause. Hours spent at school desks trying to find one joke in AMidsummer Night's Dream? Years wearing stupid tights in school playsand saying things like 'What ho, my lord' and 'Oh, look, here comesOthello, talking total crap as usual' Oh, and that is Ken Branagh'sendless uncut four-hour version of Hamlet."", """I've got a cunning plan...""","""A Merry Messy Christmas"? Allright, but the main thing is that it should be messy -- messy cake;soggy pudding; great big wet kisses under the mistletoe... """]def randomFunction(): <IMGSRC="images/callouts/2.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(2)"></A> return str(whrandom.randrange(0, 100)) <IMGSRC="images/callouts/3.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(3)"></A>def timeFunction(): <IMGSRC="images/callouts/4.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(4)"></A> return ctime(time()) <IMGSRC="images/callouts/5.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(5)"></A>def cookieFunction(): <IMGSRC="images/callouts/6.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(6)"></A> return COOKIES[whrandom.randrange(0, len(COOKIES))] <IMGSRC="images/callouts/7.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(7)"></A> </PRE><DIVCLASS="CALLOUTLIST"><DLCOMPACT="COMPACT"><DT><A href="index.lxp@lxpwrap=x1631_252ehtm.htm#C1"><IMGSRC="images/callouts/1.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(1)"></A></DT><DD>A list of pithy quotes — global to this script, so we can treat it like a kind of constant.</DD><DT><A href="index.lxp@lxpwrap=x1631_252ehtm.htm#F1"><IMGSRC="images/callouts/2.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(2)"></A></DT><DD>We will define three functions that provide some data. Later on, there's a generic <TTCLASS="CLASSNAME">DataSource</TT> class that can use one of these functions to compute some data. This function, obviously, generates random numbers.</DD><DT><A href="index.lxp@lxpwrap=x1631_252ehtm.htm#F1%2eB"><IMGSRC="images/callouts/3.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(3)"></A></DT><DD>There is no real, practical reason to choose the whrandom module over the random module. The <TTCLASS="FUNCTION">randrange(start, end, step)</TT> function returns a random integer between start and end. Note that we let this function return a <SPAN><ICLASS="EMPHASIS">string</I></SPAN>, not a number. All data produced by the datasource should be in the same format.</DD><DT><A href="index.lxp@lxpwrap=x1631_252ehtm.htm#F2"><IMGSRC="images/callouts/4.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(4)"></A></DT><DD>This function will simply produce the current date and time.</DD><DT><A href="index.lxp@lxpwrap=x1631_252ehtm.htm#F2%2eB"><IMGSRC="images/callouts/5.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(5)"></A></DT><DD>The <TTCLASS="FUNCTION">time()</TT> gives the the number of seconds elapsed since the ‘epoch' — what that means is OS-dependent. For Unix, it's January 1, 1970. The <TTCLASS="FUNCTION">ctime()</TT> converts that to nice text.</DD><DT><A href="index.lxp@lxpwrap=x1631_252ehtm.htm#F3"><IMGSRC="images/callouts/6.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(6)"></A></DT><DD>This last function will return a cookie, one of the COOKIES list.</DD><DT><A href="index.lxp@lxpwrap=x1631_252ehtm.htm#F3%2eB"><IMGSRC="images/callouts/7.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(7)"></A></DT><DD>Note how we use <TTCLASS="FUNCTION">whrandom.randrange()</TT> here to pick one from a list — the start of the range is 0, the length is the length of the cookies list.</DD></DL></DIV><PRECLASS="PROGRAMLISTING">class DataSource(QObject): <IMGSRC="images/callouts/1.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(1)"></A> def __init__(self, dataFunction, *args): <IMGSRC="images/callouts/2.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(2)"></A> apply(QObject.__init__, (self,) + args) self.timer = self.startTimer(1000) <IMGSRC="images/callouts/3.gif"HSPACE="0"VSPACE="0"BORDER="0"ALT="(3)"></A> self.dataFunction = dataFunction <IMGSRC="images/callouts/4.gif"HSPACE="0"
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?