Errata for C++ GUI Programming with Qt 4
(Updated 21 Feb 2008)

Note: This errata is for the first edition of the book. An errata for the second edition can be found on the publisher's site.

IssueResolutionReporter
The examples don't compile with Visual C++ using the Qt edition supplied on the CD. This is correct. The Windows GPL edition of Qt can only be used with the MinGW compiler as mentioned on page 5 and in the "Installing Qt" appendix on page 448. (See the errata for page 5 below.) Derek Larsson, Nicholas DiTorro, etc.
For some Mac OS X users, the examples don't build correctly. Make sure that qconfig.h (which is normally located in /Library/Frameworks/QtCore.framework/Headers) defines QT_EDITION. If it does not, then add these lines at the top of qconfig.h:
/* Qt Edition */
#ifndef QT_EDITION
#  define QT_EDITION QT_EDITION_OPENSOURCE
#endif
This should solve the problem.
Long Li
The applications chap03/spreadsheet and chap04/spreadsheet don't compile. Copy chap02/sort/sortdialog.ui to chap03/spreadsheet and to chap04/spreadsheet. (We'd used soft links but these didn't make it on to the CD.) John J. Neff
The plugins in chap05/iconeditorplugin and chap19/cursorplugin, may not install on Unix-like operating systems (e.g., Linux and Mac OS X). If this occurs it probably means that you don't have write permission for $QTDIR. Either give yourself the appropriate permissions or execute make as super user, e.g., with sudo. John J. Neff
The OpenGL application chap08/tetrahedron may not link on Unix-like operating systems (e.g., Linux and Mac OS X). Possible reasons are: the OpenGL libraries aren't installed (unlikely), or you have static .a libraries rather than dynamic .so libraries. Since Qt links to OpenGL at runtime it needs access to dynamic libraries. For more information see Link error 'XF86VidModeQueryVersion' solved. John J. Neff
Page iv. The link to the Open Publication License is wrong. The correct link is http://www.opencontent.org/openpub/. Dennis Colburn
Page 5: The phrase "If you are using Microsoft Visual C++," is incomplete. The phrase should be "If you are using Microsoft Visual C++ with a commercial edition of Qt,". (See the very first errata item.) Derek Larsson, Nicholas DiTorro et al.
Page 15: Last text paragraph begins "In filedialog.h, instead of". This should read "In finddialog.h, instead of". John J. Neff
Page 23: Third paragraph from the bottom says "then click OK." For Qt 4.1.4 and later, this should read "then click Create." K. Bischoff
Page 49: The text says "It is rendered with a checkmark in the menu and implemented as a toggle button in the toolbar". The "and implemented as a toggle button in the toolbar" part of the sentence should be dropped, since the action is never added to a toolbar. Joe Suzow
Page 85: The Spreadsheet::del() function does not announce that the spreadsheet has changed and therefore that the user should be prompted to save their changes if they exit. Here is a correct implementation:
void Spreadsheet::del()
{
    QList<QTableWidgetItem *> items = selectedItems();
    if (!items.isEmpty()) {
        foreach (QTableWidgetItem *item, items)
            delete item;
        somethingChanged();
    }
}
Michael Cartmell
Page 119: The text states that we "import all the std namespace's symbols into the global namespace", but there is no corresponding "using namespace" directive. The line "using namespace std;" should be added to the code snippet at the bottom of the page, below the #includes. Joe Suzow
Page 141: In the diagram one box is labelled "QTreeWidget". This box should be labelled "QTableWidget". Ben Cain
Page 146: The application in Figure 6.9 is said to be running on Mac OS X. Actually this screenshot was taken on Linux. Richard Reeve
Page 147: In the diagram one box is labelled "messagesTableWidget". This box should be labelled "messagesTreeWidget". Joe Suzow
Page 151: In the second line from the top we refer to a "QDockWindow". This should be "QDockWidget". Wayne Dorchak
Page 187: drawRoundRect() is called with 150 as the x-roundness, which should not exceed 99. The fifth parameter to drawRoundRect() should be 99. Joe Suzow
Page 193: The printHtml() function has a redundant line. Delete the line:
QPainter painter(&printer);
Roope Anttinen, Nikos Karapanos
Page 242: The last line of the RegExpModel::parent() function incorrectly reads:
return createIndex(row, child.column(), parentNode);
The line should be:
return createIndex(row, 0, parentNode);
Khalil Shalish
Page 264: The sentence "After the call, the items are still present clear() on the container." is incomplete. It should read: "After the call, the items are still present in the container as dangling pointers, so normally we also want to call clear() on the container." Joe Suzow
Page 268: The text refers to split()'s optional third parameter. The word "third" should be replaced with "second". Joe Suzow
Page 293: Missing footnote. There should be a footnote pointing out that for some editions of Qt it is necessary to pass suitable parameters to the configure script (such as -qt-sql-sqlite) to get Qt to compile with SQL support. If using configure, use the -h option to see what SQL switches are available. Graham Seed
Page 391: The text incorrectly mentions QMap<int, double>. It should mention QHash<int, double>. Joe Suzow
Page 394: The TransactionThread::addTransaction() function has a race condition. The race condition can be eliminated using a QWaitCondition. Apply the following patch to the example:
diff -du imagepro-old/imagewindow.cpp imagepro/imagewindow.cpp
--- imagepro-old/imagewindow.cpp	2006-10-11 17:30:59.000000000 +0200
+++ imagepro/imagewindow.cpp	2006-10-11 17:31:27.000000000 +0200
@@ -18,7 +18,7 @@
 
     connect(&thread, SIGNAL(transactionStarted(const QString &)),
             statusBar(), SLOT(showMessage(const QString &)));
-    connect(&thread, SIGNAL(finished()),
+    connect(&thread, SIGNAL(allTransactionsDone()),
             this, SLOT(allTransactionsDone()));
 
     setCurrentFile("");
diff -du imagepro-old/transactionthread.cpp imagepro/transactionthread.cpp
--- imagepro-old/transactionthread.cpp	2006-10-11 17:30:59.000000000 +0200
+++ imagepro/transactionthread.cpp	2006-10-11 17:31:27.000000000 +0200
@@ -69,36 +69,47 @@
     return QObject::tr("Converting image depth...");
 }
 
+TransactionThread::~TransactionThread()
+{
+    waitCondition.wakeAll();
+    wait();
+}
+
 void TransactionThread::addTransaction(Transaction *transact)
 {
     QMutexLocker locker(&mutex);
     transactions.enqueue(transact);
-    if (!isRunning())
-        start();
+    start();
+    waitCondition.wakeAll();
 }
 
 void TransactionThread::run()
 {
+    QImage oldImage;
     Transaction *transact;
 
     forever {
-        mutex.lock();
-        if (transactions.isEmpty()) {
-            mutex.unlock();
-            break;
+        {
+            QMutexLocker locker(&mutex);
+            if (transactions.isEmpty())
+                waitCondition.wait(&mutex);
+            if (transactions.isEmpty())
+                break;
+
+            oldImage = currentImage;
+            transact = transactions.dequeue();
         }
-        QImage oldImage = currentImage;
-        transact = transactions.dequeue();
-        mutex.unlock();
 
         emit transactionStarted(transact->message());
-
         QImage newImage = transact->apply(oldImage);
         delete transact;
 
-        mutex.lock();
-        currentImage = newImage;
-        mutex.unlock();
+        {
+            QMutexLocker locker(&mutex);
+            currentImage = newImage;
+            if (transactions.isEmpty())
+                emit allTransactionsDone();
+        }
     }
 }
 
Tim Wynants

Please send any additional errors and comments to qt-book at trolltech.com.


www.trolltech.com