Showing posts with label Qt Tips and Tricks. Show all posts
Showing posts with label Qt Tips and Tricks. Show all posts

Sunday, January 31, 2010

Twitter API client library for C++ and Qt framework

QTwitterClient is an API client library for the ubiquitous Twitter microblogging service written in C++ and using the Qt framework.

QTwitterClient is cross-platform and works on all platforms supported by Qt such as Windows, Linux, and Mac OS X, even mobile platforms like Symbian and Maemo.

Usage is very simple:
QTwitterClient *twitter = new QTwitterClient(this);
twitter->setLogin(login);
twitter->setPassword(password);

twitter->tweet("I feel really good today!");
QTwitterClient is free/open source software and licensed under LGPL 2.1 or later.

Check out QTwitterClient project page to get the source code. I will appreciate any feedback you have.

Update: Moved QTwitterClient project to Gitorious.

Pastebin API client library for C++ and Qt framework

During my pursuit of Qt Mobility Contest, I created several utility class libraries. The first is QPastebinClient, which as its name suggests, is an API client library for the popular Pastebin service written in C++ and using the Qt framework.

QPastebinClient is cross-platform and works on all platforms supported by Qt, even mobile platforms like Symbian and Maemo. Usage is very simple:
QPastebinClient *pastebin = new QPastebinClient(this);

connect(pastebin, SIGNAL(finished(QString)), this, SLOT(setPastebinUrl(QString)));
connect(pastebin, SIGNAL(failed(QString)), this, SLOT(showError(QString)));

pastebin->paste("Some worthy code");

QPastebinClient is free/open source software and licensed under LGPL 2.1 or later.

Check out QPastebinClient project page to get the sources. I will appreciate any feedback you have.

Update: Moved repository to Gitorious.

Thursday, January 28, 2010

mingw-compiled Qt app on Windows: Entry Point Not Found?

I am trying to deploy a release version of my Qt app on Windows, with Qt as shared library.

I have put the following Qt-related shared library DLL files in my application directory:
  • QtCore4.dll
  • QtGui4.dll
  • mingwm10.dll
  • libgcc_s_dw2-1.dll
  • QtContacts_tp.dll (Qt Mobility Contacts DLL)
But I still get this error:


Entry Point Not Found: The procedure entry point _Z15qAddPostRoutinePFvvE could not be located in the dynamic link library QtCore4.dll.

Why is this happening? :-(

Update: Thanks to this QtForum.org thread, it happened because I used the QtCore4.dll and QtGui4.dll from C:\Qt\2010.01\bin. After I used the DLLs from C:\Qt\2010.01\qt\bin, my application works fine! :-)

Related articles:

Sunday, January 24, 2010

"QMetaObject::connectSlotsByName: No matching signal for ..." Qt GUI Warning Message

If you get an error message (warning actually) like this:
QMetaObject::connectSlotsByName: No matching signal for on_MainWindow_destroyed()

It means you have an automatically named slot method in the main window or top-level widget.

Qt will automatically connect slots for child widgets, but not the top-level widget.

To solve this problem, you need to:
  1. Rename the slot so it doesn't start with "on_"
  2. Manually connect the slot.
connect(this, SIGNAL(destroyed()), this, SLOT(handle_MainWindow_destroyed()));

I've reported this as Qt Designer bug QT-7582.

References:

Friday, January 22, 2010

Qt Creator 1.3 Help/Documentation Not Working?

I installed Qt Creator IDE 1.3 / Qt 4.6 SDK and having a problem that the Qt Creator Help/Documentation is not working / not showing / blank.

I've found the culprit, and the reason is because:
You have used QtCreator with some Qt version before, and now have installed the same Qt version in a different location: There's a bug   that in this case the information where to get the help file is not updated.

The solution is simple:
Please try explicitly removing the entries in Tools -> Options -> Help, and either restart QtCreator, or add the qch-files from your Qt version explicitly.

Doing the above procedure returns my Qt Creator help content properly.

Wednesday, December 30, 2009

Qt/C++ Programming vs Spring/Java Development

After a few days with Qt and reunion with C++ (after almost 10 years), I have some thoughts about Qt and C++ development when compared to my experience with Spring and Java.

FeatureQt/C++Spring/Java
Memory management
Qt makes C++ more bearable by cleaning up child objects automatically if its parent is destroyed. But still far from what Java has to offer, new and forget. ;-)
Java is clear winner here. Furthermore, Spring makes object lifecycle ("beans") even more automatic and controlled. You can have singleton beans, prototype scoped beans, etc. And autowiring.
Dependency Injection
Aside from Qt's standard signals and slots, and Qt Designer for wiring widgets, there isn't much. Or maybe I haven't found it.
Qt is no match for Spring's powerful dependency injection capabilities, whether using XML configuration or (even more) annotations. It's not a Java feature, but it's not specific to Spring either. Other frameworks like Guice and JBoss Seam also have this feature, especially with the recent WebBeans aka Java Context and Dependency Injection (CDI) aka JSR-299.
Event Handling
Qt has standard signals and slots, which is superior when compared to traditional C/C++, or even Java for that matter. (now I realized what the fuss with signals and slots is all about!)
No support for free-form publish-subscribe event handling, only declared signals.
Java has Observer pattern, Listener pattern, and recently (thanks to OSGi) the Whiteboard pattern.
The closest to direct connection in Java is properties with interface types, a.k.a.:
private ActionListener clickListener;
Spring can help with wiring, which reliefs much of the pain.
Granted, all of them are inferior compared to Qt's signals and slots, with agreed conventions semi-message-passing capability (with QueueConnection and BlockingQueueConnection).
Surprisingly, even Dojo has dojo.connect which is very similar (if not exactly) like Qt's signals and slots and dojo.publish for free-form publish-subscribe messaging/event handling.
Fortunately, both techniques are trivially implemented in Java with help of an integration library such as Apache Camel or Spring Integration. This really needs to be part of core Java specs.
Widgets
I guess this is the strength of Qt. I like it, and I like how it looks, especially with the new GTK+ style. Blends in with other Ubuntu apps.
I mainly develop web-based Spring apps with Dojo AJAX toolkit, not desktop ones, so I can't really compare. However, I've had some experience with Swing GUI and Eclipse RCP (SWT) apps. I can say Qt's feel smoother both visually and performance-wise.
Programming either Swing or SWT is more pleasant than Qt, due to Java.
Performance
Excellent. Both building and running.
Very good. Frankly, I don't think Java is that slow anymore. I haven't yet proven myself that Java apps can be faster than C++ counterparts, but I'm sure there are such cases.
Build & Dependency Management
Horrible!
Qt Creator and qmake did its job, but there's no dependency management, library hell, etc.
Dependencies must be compiled with their respective tooling, sometimes conflicting.
Real-life example: Qt Mobility 1.0 TP2 can't be compiled with GCC 4.4, needs GCC 4.3.
Excellent!
Pick your poison: Eclipse's, NetBeans', Maven, Ant + Ivy, or plain Ant. For some people, IntelliJ's.
Yes the tools are quite fragmented, but the most manual thing you needed to do upon tooling conflict is download the (binary! thank God!) dependencies manually and put them on correct locations.
Works on all platforms.

Conclusion

Overall, I'd say Spring/Java development is more enjoyable than Qt/C++ programming.

Java's lack of convenient event handling mechanism disturbs me. Although integration libraries cure that itch to some extent, most Java developers will code them manually. Besides, not every project uses integration libraries, or even if they do, they might use different libraries, leading to redundancy and other issues.

Tuesday, December 29, 2009

Installing Qt Mobility Libraries on Ubuntu

It's time for me to jump into Qt Mobility development. Yaay!

Here's my steps to prepare Qt Mobility development. I'm using Ubuntu 9.10 Karmic Koala.
  1. Make sure you have installed Qt 4.6.
  2. Install checkinstall package if you haven't.
  3. Install network-manager-dev package. This will be used by the Bearer API and System Information API.
  4. Install libgstreamer0.10-dev package. This will be used by the Multimedia API implementation.
  5. Download Qt Mobility library sources.
  6. Unpack the Qt Mobility distribution to a folder.
  7. Open a terminal on that folder.
  8. Set the PATH to Qt 4.6.x libraries:

    $ export PATH=/opt/qtsdk-2010.01/qt/bin:$PATH
    
  9. Set PKG_CONFIG_PATH:

    $ export PKG_CONFIG_PATH=/usr/lib/pkgconfig
    
  10. Run:

    $ ./configure

$ ./configure 
Configuring Qt Mobility

Checking available Qt ... 4.6.0
Checking QMF ... Not Found
Checking NetworkManager ... OK
Checking CoreWLAN (MacOS 10.6) ... Not Found
Generating Mobility Headers...
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QNetworkConfiguration
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QNetworkConfigurationManager
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QNetworkSession
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QValueSpaceSubscriber
Create header /opt/qt-mobility-src-1.0.0-tp2/include/SymbianSettingsLayer
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QValueSpacePublisher
Create header /opt/qt-mobility-src-1.0.0-tp2/include/PathMapper
Create header /opt/qt-mobility-src-1.0.0-tp2/include/PathData
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QNmeaPositionInfoSource
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QGeoPositionInfo
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QGeoSatelliteInfoSource
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QGeoCoordinate
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QGeoSatelliteInfo
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QGeoPositionInfoSource
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QGeoAreaMonitor
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QServiceContext
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QServiceManager
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QServicePluginInterface
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QAbstractSecuritySession
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QServiceInterfaceDescriptor
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QServiceFilter
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QSystemInfo
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QSystemNetworkInfo
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QSystemDisplayInfo
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QSystemStorageInfo
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QSystemDeviceInfo
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QSystemScreenSaver
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QContactDetailDefinition
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QContactFilter
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QContactDetailDefinitionField
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QContactChangeSet
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QContactAbstractRequest
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QContactActionFactory
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QContactManagerEngine
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QContactAction
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QContactDetail
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QContactId
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QContactActionDescriptor
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QContact
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QContactRelationship
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QContactSortOrder
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QContactManager
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QContactManagerEngineFactory
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QMediaPlaylistProvider
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QVideoOutputControl
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QMetaDataControl
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QMediaControl
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QLocalMediaPlaylistProvider
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QMediaRecorderControl
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QMediaImageViewer
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QMediaPlaylistReader
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QMediaPlaylistWriter
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QMediaPlaylistIOPlugin
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QVideoEncoderControl
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QMediaStreamsControl
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QMediaService
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QMediaPlaylistControl
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QMediaPlayer
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QMediaPlaylistNavigator
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QGraphicsVideoItem
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QMediaServiceProviderHint
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QMediaServiceProvider
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QMediaRecorder
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QVideoRendererControl
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QAudioDeviceControl
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QAudioEncoderControl
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QRadioTunerControl
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QVideoDeviceControl
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QAudioEncoderSettings
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QVideoEncoderSettings
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QImageEncoderSettings
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QMediaResource
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QMediaPlaylist
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QMediaPlayerControl
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QVideoWidget
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QMediaServiceProviderPlugin
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QVideoWindowControl
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QImageEncoderControl
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QVideoWidgetControl
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QMediaFormatControl
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QRadioTuner
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QAudioCaptureSource
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QMediaObject
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QAudioFormat
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QMediaContent
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QMessageFolderFilter
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QMessageFilter
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QMessageFolderOrdering
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QMessageFolder
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QMessageId
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QMessageContentContainer
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QMessageStore
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QMessageAccountOrdering
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QMessage
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QMessageAddress
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QMessageServiceAction
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QMessageFolderId
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QMessageContentContainerId
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QMessageAccountFilter
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QMessageOrdering
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QMessageAccountId
Create header /opt/qt-mobility-src-1.0.0-tp2/include/QMessageAccount
Running qmake...
Reading /opt/qt-mobility-src-1.0.0-tp2/src/src.pro
 Reading /opt/qt-mobility-src-1.0.0-tp2/src/global/global.pro
 Reading /opt/qt-mobility-src-1.0.0-tp2/src/serviceframework/serviceframework.pro
 Reading /opt/qt-mobility-src-1.0.0-tp2/src/bearer/bearer.pro
Project MESSAGE: NetworkManager backend requires Qt DBus support
 Reading /opt/qt-mobility-src-1.0.0-tp2/src/location/location.pro
 Reading /opt/qt-mobility-src-1.0.0-tp2/src/contacts/contacts.pro
 Reading /opt/qt-mobility-src-1.0.0-tp2/src/multimedia/multimedia.pro
 Reading /opt/qt-mobility-src-1.0.0-tp2/src/publishsubscribe/publishsubscribe.pro
 Reading /opt/qt-mobility-src-1.0.0-tp2/src/versit/versit.pro
 Reading /opt/qt-mobility-src-1.0.0-tp2/src/systeminfo/systeminfo.pro
Reading /opt/qt-mobility-src-1.0.0-tp2/tools/tools.pro
 Reading /opt/qt-mobility-src-1.0.0-tp2/tools/servicefw/servicefw.pro
 Reading /opt/qt-mobility-src-1.0.0-tp2/tools/servicexmlgen/servicexmlgen.pro
 Reading /opt/qt-mobility-src-1.0.0-tp2/tools/vsexplorer/vsexplorer.pro
 Reading /opt/qt-mobility-src-1.0.0-tp2/tools/qcrmlgen/qcrmlgen.pro
Reading /opt/qt-mobility-src-1.0.0-tp2/plugins/plugins.pro
 Reading /opt/qt-mobility-src-1.0.0-tp2/plugins/contacts/contacts.pro
 Reading /opt/qt-mobility-src-1.0.0-tp2/plugins/multimedia/multimedia.pro
Package gstreamer-interfaces-0.10 was not found in the pkg-config search path.
Perhaps you should add the directory containing `gstreamer-interfaces-0.10.pc'
to the PKG_CONFIG_PATH environment variable
No package 'gstreamer-interfaces-0.10' found
Package gstreamer-audio-0.10 was not found in the pkg-config search path.
Perhaps you should add the directory containing `gstreamer-audio-0.10.pc'
to the PKG_CONFIG_PATH environment variable
No package 'gstreamer-audio-0.10' found
Package gstreamer-video-0.10 was not found in the pkg-config search path.
Perhaps you should add the directory containing `gstreamer-video-0.10.pc'
to the PKG_CONFIG_PATH environment variable
No package 'gstreamer-video-0.10' found
  Reading /opt/qt-mobility-src-1.0.0-tp2/plugins/multimedia/m3u/m3u.pro
  Reading /opt/qt-mobility-src-1.0.0-tp2/plugins/multimedia/audiocapture/audiocapture.pro
  Reading /opt/qt-mobility-src-1.0.0-tp2/plugins/multimedia/v4l/v4l.pro
Reading /opt/qt-mobility-src-1.0.0-tp2/doc/doc.pro
 Reading /opt/qt-mobility-src-1.0.0-tp2/doc/src/snippets/snippets.pro
  Reading /opt/qt-mobility-src-1.0.0-tp2/doc/src/snippets/qtcontactsdocsample/qtcontactsdocsample.pro

configure has finished. You may run make or gmake to build the project now.
  1. Run: sudo checkinstall
    If you can't or don't want to use checkinstall, do:


    $ make
    $ make install
    


  2. Be very patient (again!)
I'm having unexpected unpleasant surprise here, the build stops early with an error:

g++ -c -pipe -g -fvisibility=hidden -fvisibility-inlines-hidden -Wall -W -D_REENTRANT -fPIC -DQT_BUILD_CFW_LIB -DQT_MAKEDLL -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/local/Trolltech/Qt-4.6.0/mkspecs/linux-g++ -I. -I/usr/local/Trolltech/Qt-4.6.0/include/QtCore -I/usr/local/Trolltech/Qt-4.6.0/include/QtNetwork -I/usr/local/Trolltech/Qt-4.6.0/include -I../global -I../../build/Debug/QtPublishSubscribe/moc -o ../../build/Debug/QtPublishSubscribe/qmallocpool.o qmallocpool.cpp
In file included from qmallocpool.cpp:64:
dlmalloc.c: In function ‘void QtMobility::dlmalloc_stats()’:
dlmalloc.c:4725: error: cannot convert ‘QtMobility::_IO_FILE*’ to ‘FILE*’ for argument ‘1’ to ‘int QtMobility::fprintf(FILE*, const char*, ...)’
dlmalloc.c:4727: error: cannot convert ‘QtMobility::_IO_FILE*’ to ‘FILE*’ for argument ‘1’ to ‘int QtMobility::fprintf(FILE*, const char*, ...)’
dlmalloc.c:4729: error: cannot convert ‘QtMobility::_IO_FILE*’ to ‘FILE*’ for argument ‘1’ to ‘int QtMobility::fprintf(FILE*, const char*, ...)’
make[2]: *** [../../build/Debug/QtPublishSubscribe/qmallocpool.o] Error 1
make[2]: Leaving directory `/opt/qt-mobility-src-1.0.0-tp2/src/publishsubscribe'
make[1]: *** [sub-publishsubscribe-make_default] Error 2
make[1]: Leaving directory `/opt/qt-mobility-src-1.0.0-tp2/src'
make: *** [sub-src-make_default-ordered] Error 2 

This is a known Qt Mobility bug with GCC 4.4, which Ubuntu 9.10 uses by default.

To solve this problem, install gcc-4.3 package and g++-4.3 package. Update the symlinks too:

$ sudo ln -sf gcc-4.3 /usr/bin/gcc
$ sudo ln -sf g++-4.3 /usr/bin/g++

Update: Even with GCC / G++ 4.3, I still experience yet another problem:

g++ -c -pipe -g -fvisibility=hidden -fvisibility-inlines-hidden -Wall -W -D_REENTRANT -fPIC -DQT_BUILD_SYSINFO_LIB -DQT_MAKEDLL -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/local/Trolltech/Qt-4.6.0/mkspecs/linux-g++ -I. -I/usr/local/Trolltech/Qt-4.6.0/include/QtCore -I/usr/local/Trolltech/Qt-4.6.0/include/QtNetwork -I/usr/local/Trolltech/Qt-4.6.0/include/QtGui -I/usr/local/Trolltech/Qt-4.6.0/include -I../global -I../../build/Debug/QtSystemInfo/moc -o ../../build/Debug/QtSystemInfo/qsysteminfo_linux.o qsysteminfo_linux.cpp
qsysteminfo_linux.cpp: In member function ‘void QtMobility::QSystemStorageInfoPrivate::mountEntries()’:
qsysteminfo_linux.cpp:1370: warning: comparison between signed and unsigned integer expressions
In file included from qsysteminfo_linux.cpp:2073:
../../build/Debug/QtSystemInfo/moc/moc_qsysteminfo_linux_p.cpp: In member function ‘bool QtMobility::QSystemScreenSaverPrivate::isScreenSaverActive()’:
../../build/Debug/QtSystemInfo/moc/moc_qsysteminfo_linux_p.cpp:47: error: invalid use of qualified-name ‘QtMobility::QSystemInfoPrivate::staticMetaObject’
../../build/Debug/QtSystemInfo/moc/moc_qsysteminfo_linux_p.cpp:57: error: a function-definition is not allowed here before ‘{’ token
../../build/Debug/QtSystemInfo/moc/moc_qsysteminfo_linux_p.cpp:62: error: a function-definition is not allowed here before ‘{’ token
../../build/Debug/QtSystemInfo/moc/moc_qsysteminfo_linux_p.cpp:70: error: a function-definition is not allowed here before ‘{’ token
qsysteminfo_linux.cpp:2075: error: expected `}' at end of input
qsysteminfo_linux.cpp: At global scope:
qsysteminfo_linux.cpp:2075: error: expected `}' at end of input
make[2]: *** [../../build/Debug/QtSystemInfo/qsysteminfo_linux.o] Error 1
make[2]: Leaving directory `/opt/qt-mobility-src-1.0.0-tp2/src/systeminfo'
make[1]: *** [sub-systeminfo-install_subtargets] Error 2
make[1]: Leaving directory `/opt/qt-mobility-src-1.0.0-tp2/src'
make: *** [sub-src-install_subtargets-ordered] Error 2 

I reported this to Qt as bug QTMOBILITY-46. Hopefully it gets resolved soon, or a workaround is provided.

Update: I got word from Lorn Potter from Nokia/TrollTech/Qt. To patch it, run:

patch src/systeminfo/qsysteminfo_linux.cpp

then paste in:

diff --git a/src/systeminfo/qsysteminfo_linux.cpp
b/src/systeminfo/qsysteminfo_linux.cpp
index f795c4f..e0d1a4b 100644
--- a/src/systeminfo/qsysteminfo_linux.cpp
+++ b/src/systeminfo/qsysteminfo_linux.cpp
@@ -2065,8 +2065,8 @@ bool QSystemScreenSaverPrivate::isScreenSaverActive()
                 return reply.value();
             }
         }
-    }
 #endif
+    }
     return false;
 }

and press Ctrl+D.

After doing the above, I have successfully compiled Qt Mobility 1.0 TP2. Yaay!

Now you should add add /opt/qt-mobility-src-1.0.0-tp2/lib folder to your LD_LIBRARY_PATH environment variable.

To add Qt Mobility documentation in Qt Creator: Go to Tools -> Options -> Help -> Add. Then browse /opt/qt-mobility-src-1.0.0-tp2/doc/qch/qtmobility.qch.

See also:

"undefined reference to vtable" Error

I'm having a very strange problem with Qt library (and C++ in general), this message:

undefined reference to vtable `...SomeClass...`

It frustrates me at first. I still don't know why it happens, but I know how to solve it in my case.

As an example, this code:

#include <QObject>
#include <stdio.h>

class HelloWorld : public QObject
{
Q_OBJECT
signals:
    void done();

public slots:
    void sayHello() {
        printf("Hello World!\n");
        done();
    }

};

works fine when put into helloworld.h and called by main.cpp.

However, when it's put directly into main.cpp... it throws the (linker) error.

It seems all Qt objects must be put into their own H/CPP pair. At least that's what it makes me think.

Reference: qt-interest mailing list archive - undefined reference to vtable...

Syntax Highlight Blogger Posts Automatically

When posting source code in a blog post, you surely want it to be syntax highlighted. However, doing it manually is painful. I'll show you how to syntax highlight source code automatically, and works in Blogger.

Note: This isn't a Qt tip, but I bet you'll find it useful. :-)

My Old Technique: tohtml.com


At first I used tohtml.com's service to do syntax highlighting. Which works fine, by the way, but generates quite large HTML, especially if the code is long.

And it lacks the cool features like line numbering and copy-to-clipboard.

Enter... the JavaScript Syntax Highlighter!

Activating Alex Gorbatchev's JavaScript Syntax Highlighter


The syntax highlighting engine that we're gonna use is the excellent Syntax Highlighter by Alex Gorbatchev.

To install it, simply add the following code inside the blog template's HEAD:

<!-- Syntax Highlighter: Begin -->
<link href='http://alexgorbatchev.com/pub/sh/current/styles/shCore.css' rel='stylesheet' type='text/css'/> 
<link href='http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css' rel='stylesheet' type='text/css'/> 
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js' type='text/javascript'></script> 
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPlain.js' type='text/javascript'></script> 
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushBash.js' type='text/javascript'></script> 
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCpp.js' type='text/javascript'></script> 
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushXml.js' type='text/javascript'></script> 
<script language='javascript'> 
SyntaxHighlighter.config.bloggerMode = true;
SyntaxHighlighter.config.clipboardSwf = 'http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf';
SyntaxHighlighter.all();
</script> 
<!-- Syntax Highlighter: End -->

To edit the template in Blogger, go to Layout -> Edit HTML -> Edit Template.

Using Syntax Highlighter


To use it in a blog post, surround the code you want to post with PRE tag and either class="brush: xml" or class="brush: cpp" depending on the programming language (XML or C++ respectively).

You need to escape the content first before pasting into Blogger's post editor, using Quick Escape.

Syntax Highlighted Examples


Syntax highlighting for C++ (Qt!) code:

#include <QtGui/QApplication>
#include "mainwindow.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

Source HTML for the above is:

<pre class="brush: cpp">#include &lt;QtGui/QApplication&gt;
#include &quot;mainwindow.h&quot;

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}</pre>

To get the following XML code syntax highlighted:

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  </widget>
 <layoutdefault spacing="6" margin="11"/>
 <resources/>
 <connections/>
</ui>

Put these in "Edit HTML": (WARNING! The following may hurt your eyes!)

<pre class="brush: xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;ui version=&quot;4.0&quot;&gt;
 &lt;class&gt;MainWindow&lt;/class&gt;
 &lt;widget class=&quot;QMainWindow&quot; name=&quot;MainWindow&quot;&gt;
  &lt;/widget&gt;
 &lt;layoutdefault spacing=&quot;6&quot; margin=&quot;11&quot;/&gt;
 &lt;resources/&gt;
 &lt;connections/&gt;
&lt;/ui&gt;</pre>

Looks really ugly, huh? The escaping is unfortunately, necessary.

In Blogger, when you got from "Edit HTML" to "Compose" (WYSIWYG) it gets even uglier. This usually only applies for XML-ish code.

Quick Escape: My Version


As I'm writing this, the Quick Escape online service I previously mentioned goes down... leaving me powerless to escape my code examples.

Fortunately, escaping HTML is easy to do with any programming toolkit. Hereby I choose Ruby language.

Save the following code as escapehtml.rb:

#!/usr/bin/env ruby
require 'cgi'
print CGI::escapeHTML $stdin.read

You can use it by simply executing it in a terminal, typing something then press Ctrl+D. Or by piping any content or file into it.

Credits


I found this technique from Awesome syntax highlighting made easy by Carter Cole. In fact, I simply reiterate here what he wrote there.

Demonstrating Qt's Automatic Destructor

Mas Ariya Hidayat told me that Qt had automatic memory management / garbage collection features. It's one feature that made me more interested in Java, C#, Ruby, PHP, and Python, than C and C++.

In practice, this means that Qt objects are automatically deleted when its parent is deleted.

By "Qt object" I mean any object that inherits QObject.

From qt-interest discussion: Qt Class Destructor - No Need for Delete:
If the constructor for the class expects a QObject* parent parameter, and you pass it one, then you can expect that when the parent dies, the child will also die. If it does not expect such a parameter, or it expects one but you pass it 0, or do not pass it anything and thus it defaults to 0, then you will need to clean the object up yourself later with delete.

Demo-ing Automatic Destructor on Hello World App


Let's take my previous Hello World app and add a destructor.

helloworld.cpp

...

HelloWorld::~HelloWorld() {
    printf("Bye bye...!\n");
}

...

and use the new operator to create HelloWorld object:

main.cpp :

...

    HelloWorld *helloWorld = new HelloWorld(&a);
    QObject::connect(helloWorld, SIGNAL( done() ), &a, SLOT( quit() ), Qt::QueuedConnection);
    QTimer::singleShot(0, helloWorld, SLOT( sayHello() ));

...

Run the application, and we get:

Starting /home/ceefour/Sandbox/helloworld-console/helloworld-console...
Starting up...
Hello World!
Bye bye...!
/home/ceefour/Sandbox/helloworld-console/helloworld-console exited with code 0

Works as advertised! The HelloWorld::~HelloWorld() destructor is called, and there's no need to delete the object explicitly.

The secret recipe is this particular line:

HelloWorld *helloWorld = new HelloWorld(&a);

It creates the HelloWorld object as a child of Qt application.

In effect, when Qt application object is destroyed, the HelloWorld object gets destroyed first.

If we change it to this:

HelloWorld *helloWorld = new HelloWorld;

The destructor won't be called automatically, and we have to call it ourselves.

I don't think it's technically an automatic memory management with garbage collection, but when used properly, it's very useful.