Saturday, November 28, 2009

QtFindReplaceDialog - a Find/Replace Qt dialog

Since I have not found an implementation of a Find /Replace dialog to be used in Qt text editor based applications, I thought I'd try to create one myself:

QtFindReplaceDialog is an implementation of a Find/Replace Qt dialog to be used in qt text edit based applications. A simple Find (only) dialog is also provided. The dialogs can be used as a library, or simply by importing the sources into your own applications. QtFindReplaceDialog is free and open source LGPL software.



Thursday, November 05, 2009

Compiling Qt 4.6 from sources

If you feel like trying the new Qt 4.6, which is currently in beta, and if you're using Linux, for which it is available only in source code package, or if you need the current development version from the git repository (for instance, for building the git repository version of Qt-Creator, you'll have to compile qt from sources.

This is quite straightforward, but I'll blog it here, in case it might provide some help for those who never compiled it.

If you obtained the source package, then you'll need to unpack it somewhere in your home.

If you want the git version (of course you need the git program), you'll first obtain the sources from the git repository:

git clone git://gitorious.org/qt/qt.git
and then switch to the 4.6 branch
cd qt
git checkout -b 4.6 origin/4.6
Now, instead of compiling qt in the same directory where the sources are, let's make a shadow build, so that the source directory will stay untouched; this will also allow us to do possible several builds of the library (e.g., we may want to do a static build of the library, a debug build, etc.). Thus we create a build directory where we'll run the compilation (note that at the moment the build directory must be at the same level, thus we must not create the build directory inside the source directory).

Thus, for instance, this are the directories I have for building qt
bettini@bettini-desktop-karmic:~/install/qt-git$ ll
total 8
drwxr-xr-x 2 bettini bettini 4096 2009-11-04 21:33 build
drwxr-xr-x 17 bettini bettini 4096 2009-11-04 21:33 qt
(where qt is where you have the qt sources; in case you got the source archive, this directory might be called something like qt-everywhere-opensource-src-4.6.0-beta1).

Now, let's enter the build directory and run the configure script. If you don't pass any -prefix option to configure, the library will be built to be installed into the directory /usr/local/Trolltech/Qt-4.6.0/):
cd build
../qt/configure
you'll have to answer some questions, and then you'll be ready to compile:
Which edition of Qt do you want to use ?

Type 'c' if you want to use the Commercial Edition.
Type 'o' if you want to use the Open Source Edition.

Preparing build tree...

This is the Qt/X11 Open Source Edition.

You are licensed to use this software under the terms of
the Lesser GNU General Public License (LGPL) versions 2.1.

Type 'L' to view the Lesser GNU General Public License version 2.1.
Type 'yes' to accept this license offer.
Type 'no' to decline this license offer.

Do you accept the terms of the license?


Qt is now configured for building. Just run 'make'.
Once everything is built, you must run 'make install'.
Qt will be installed into /usr/local/Trolltech/Qt-4.6-git

To reconfigure, run 'make confclean' and 'configure'.
Now you're ready to run make and wait for about a couple of hours (even more if you don't have a fast machine); of course you may want to tweak the configuration so that you don't build some parts of qt (e.g., the examples); you may want to take a look at configure options by running configure --help.

After compilation ended, you can install the library; if you chose to install it in a path which is not your home, remember that you need superuser privileges:
sudo make install
When this ended, you'll have your qt installed in the path specified at configuration time (or the default one), e.g.:
bettini@bettini-prog-karmic:~$ ll /usr/local/Trolltech/Qt-4.6.0/
total 364
drwxr-xr-x 2 root root 4096 2009-11-05 07:30 bin
drwxr-xr-x 22 root root 4096 2009-11-05 07:29 demos
drwxr-xr-x 5 root root 4096 2009-11-05 07:30 doc
drwxr-xr-x 36 root root 4096 2009-11-05 07:29 examples
drwxr-xr-x 21 root root 4096 2009-11-05 07:28 include
drwxr-xr-x 3 root root 4096 2009-11-05 07:28 lib
drwxr-xr-x 96 root root 4096 2009-11-05 07:30 mkspecs
drwxr-xr-x 2 root root 4096 2009-11-05 07:28 phrasebooks
drwxr-xr-x 10 root root 4096 2009-11-05 07:28 plugins
-rw-r--r-- 1 root root 332881 2009-10-13 09:43 q3porting.xml
Note that sometimes documentation is not installed (you can take a look at the doc directory which should have html and qch subdirectories). I experienced this if I use a different prefix at configuration time. If this is the case, you need to first build explicitly the documentation with make docs and then, run the same configure command again (i.e., with the same options), and then run the make install command another time, and the documentation should be installed correctly.

Now, you're ready to enjoy the qtdemo, by running /usr/local/Trolltech/Qt-4.6.0/bin/qtdemo

Now, if you have another version of qt already installed in your system (e.g., the one packaged for your distribution) and you want to use the one you've just compiled it?

Well, thanks to qmake, this is quite easy: it's just a matter of invoking the qmake of your compiled version of qt (instead of the one in the system path).

For instance, let's take the mdi example that comes with qt, and let's take, for instance, the one already installed in your system (if you don't have qt examples already installed from your distribution, you can still take the one that is in the sources you downloaded), and copy it into a local folder:
bettini@bettini-prog-karmic:~/tmp/qt$ cp -rf /usr/lib/qt4/examples/mainwindows/mdi .
cd mdi

If I want to build this example using the version of qt we've just compiled it's just a matter of running
/usr/local/Trolltech/Qt-4.6.0/bin/qmake mdi.pro
Now, if I run make, the g++ compiler will be invoked with the right include path and library path for our compiled version of qt:
make
For instance, here's some output (note the -I and -L options):
g++ -c -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_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/QtGui -I/usr/local/Trolltech/Qt-4.6.0/include -I. -o main.o main.cpp
...
/usr/local/Trolltech/Qt-4.6.0/bin/moc -DQT_NO_DEBUG -DQT_GUI_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/QtGui -I/usr/local/Trolltech/Qt-4.6.0/include -I. mdichild.h -o moc_mdichild.cpp
...
g++ -Wl,-O1 -Wl,-rpath,/usr/local/Trolltech/Qt-4.6.0/lib -o mdi main.o mainwindow.o mdichild.o moc_mainwindow.o moc_mdichild.o qrc_mdi.o -L/usr/local/Trolltech/Qt-4.6.0/lib -lQtGui -L/usr/local/Trolltech/Qt-4.6.0/lib -L/usr/X11R6/lib -lQtCore -lpthread
By the way, note that the right version of the moc compiler is used (and the same holds for uic if your application needs it).

If you now run the mdi program, and choose the Help -> About Qt menu item, you'll get the proof you're using your version of qt 4.6


Let's do some more experiments, and recompile the mdi example with the system version of qt (thus, it's better to get rid of the mdi directory and get a fresh new copy of the mdi example). Now we use the system version of qmake:
qmake -version
QMake version 2.01a
Using Qt version 4.5.2 in /usr/lib
and let's build the example this way
qmake mdi.pro
make
Note that the compiler options are now different

g++ -c -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I. -o main.o main.cpp
...
/usr/bin/moc-qt4 -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I. mdichild.h -o moc_mdichild.cpp
...
g++ -c -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I. -o qrc_mdi.o qrc_mdi.cpp
g++ -Wl,-O1 -o mdi main.o mainwindow.o mdichild.o moc_mainwindow.o moc_mdichild.o qrc_mdi.o -L/usr/lib -lQtGui -lQtCore -lpthread
If we run the application and select the about qt menu item we can see that we have the 4.5 version of qt:


However, you can run this application, which is built using qt 4.5, so that it uses the 4.6 version of the library you compiled from source (assuming that we are using dynamically linked library):
LD_LIBRARY_PATH=/usr/local/Trolltech/Qt-4.6.0/lib ./mdi
This will force the dynamic linker to use the 4.6 version of the dynamic libraries.

Again, you can get the evidence using the about qt menu item.

This is possible due to version 4.6 being backward compatible.

Have fun with Qt :-)