yfx2003 |
2016-04-24 20:22 |
原书的勘误——已经在中文版中得到了更正
Rapid GUI Programming with Python and Qt
Errata
ISBN-10: 0132354187 – ISBN-13: 978-0132354189
Pages 540 & 541. Rare and subtle bug in the threaded server example (chap19/building- servicesserver.py—this doesn't apply to the non-threaded Chapter 18 versions of this server) | The code presented on page 540 in the run() method has a failure mode: If a client makes a connection but sends incomplete data (or no data), e.g., due to a poor connection (e.g., wireless), or due to a bug in the client, the thread will wait forever. This doesn't block the rest of the program or stop other threads being created and used, but if errors of this kind kept happening, the server would consume more and more memory. Here is the code that the run() method ought to start with (and that is now in all the archives): def run(self):socket = QTcpSocket()if not socket.setSocketDescriptor(self.socketId):self.emit(SIGNAL("error(int)"), socket.error())returnwhile socket.state() == QAbstractSocket.ConnectedState:nextBlockSize = 0stream = QDataStream(socket)stream.setVersion(QDataStream.Qt_4_2)if (socket.waitForReadyRead() andsocket.bytesAvailable() >= SIZEOF_UINT16):nextBlockSize = stream.readUInt16()else:self.sendError(socket, "Cannot read client request")returnif socket.bytesAvailable() < nextBlockSize:if (not socket.waitForReadyRead(60000) orsocket.bytesAvailable() < nextBlockSize):self.sendError(socket, "Cannot read client data")return... The first if statement inside the while loop waits for up to 30 seconds (the default for QTcpSocket.waitForReadyRead()) and if by then it has the size of the block it reads the size and continues to the second if statement. Otherwise it sends an error message to the client and returns (thus terminating the thread and allowing its memory to be reclaimed). Similarly, in the second if statement inside the loop, if we haven't received the entire block of data we are expecting we wait for up to two minutes for the data to become available, and if all the data hasn't arrived by then we send the client an error message and return, again terminating the thread. | Nicola Murino (who both reported the bug & tested my solution) | Errata for the First Printing only (additional to the errata above—these are all fixed in the Second and subsequent printings) | Issue | Resolution | Reporter | Page 17. Incorrect forward reference. | The forward reference to Chapter 4 should be to Chapter 3. | Burkhard Lück | Page 19. Bad hypenation. | Namespace is hypenated as names-pace instead of name-space. | Lorenz Quack and Steve Shortess | Page 30. Typo in the penultimate paragraph. | In the paragraph beginning "Now we have changed the names tuple...", change names[:1] to names[:2]. | Giovanni Cavallin | Page 33. Missing item from list. | All the fruit lists shown at the bottom of this page should have 'Pear' in front of 'Quince'. | Mark M. Henwood | Page 51. Incorrect variable name in code snippet. | In the first code snippet change print president, presidents[key] to print key, presidents[key]. | Chris O'Halloran | Page 73. Poorly specified exercise. | In Exercise 2 change the text “For every lowercase character in text” to “For every character in a lowercased copy of text”. | Oleksandr Moskalenko | Page 82. Although the __cmp__() method works as written, it doesn't take advantage of the fact that area is a property. | Change the return line to: return cmp(self.area, other.area) This correction has been made to the example source code. | Ralph Wagner | Page 96. Missing period | The period is missing from the end of the first sentence of the second paragraph. | Kazuyoshi Furutaka | Page 117. Incorrect word. | In the last line of the paragraph below the screenshot change the word "encodings" to the phrase "character sets". | Erik Dalén | Page 126. Incorrect word. | Change the last word in the second paragraph from “readlines()” to the phrase, “the file handle as an iterable” (Kurt Welgehausen also suggested an improvement to the code shown on page 125—this is now in the tarball and zip file.) | Kurt Welgehausen | Page 162. Typo in the first sentence of the Summary. | Change "showned" to "showed". | Lorenz Quack | Page 163. Poor solution to exercise. | The solution in the archives has been improved by removing some redundant lines and by rewriting the up() and down() methods. | Alexander Kanevskiy and Oleksandr Moskalenko | Pages 333 and 460. Two blank lines instead of one separate a paragraph from a code snippet on each of these pages. | There's nothing missing, so just ignore the blank space. (I made a mistake when I typeset these pages.) | Author | Page 403. Typo in the first code snippet. | Replace page-break-after=always; with page-break-after:always;. This is now fixed in printing.pyw's source code, and gives proper page breaks but it also outputs an extra blank page at the end. A new version, printing2.pyw has been added to the source code with this fix and improved code so that no spurious blank page is output. It also puts the footer that appears when using QPainter a bit lower. | Benno Dielmann | Page 463. Workaround for Qt <= 4.3.3/SQLite bug. | The QTableView showing the log records sometimes shows spurious blank rows when using SQLite; the workaround is to add the line self.logModel.reset() just before the select() call. (The workaround was provided by Sibylle Koczian and is now in the tarball and zip file.) | Sibylle Koczian | Page 465. Missing : in code snippet. | In the page's main code snippet there's a colon missing after if not QSqlDatabase.database().commit(). | Carla Paredes | Page 615. Misplaced gzip module index entry. | This entry appears at the end of the `Q's instead of the end of the `G's on page 596 (i.e., it was filed as "qzip" instead of "gzip"). | Robert Withrow |
Top |
|