Friday, February 14, 2014

Qt Creator, QCustomPlot and PostgreSQL

Quick Links


What is Qt?

Qt is a cross-platform project developed for C++ programmers to build effective visualizations for various applications. On Windows, it can run either on the Visual Studio compiler or on the MinGW (Mimimalist GNU for Windows) compiler but the setup file for both of them are different. The setup includes all the necessary binaries and headers to build a Qt project. It also comes with the Qt Creator tool to facilitate the development of a GUI for the programmer’s application. The Qt Assistant tool can be used for any reference regarding the complete Qt project. It includes all the classes, functions that are used to develop the project. The setup file for the complete package is available for free from their official website: http://qt-project.org/downloads. But, it is important to download the correct setup file according to the compiler the user wishes to run it with.

Just like any other project, Qt has a whole lot of example projects to make the programmer get accustomed to the development environment. Even though Qt includes all C++ headers, it is generally advisable to use Qt’s corresponding custom headers to make much better use of the environment. For example, even though one can include <string.h> to perform string operations in his application, it’s more advisable to use the QString data type because the standard “string” data type may not interface with many Qt functions. Similarly, “qDebug()”  is used instead of “std::cout”. Once the programmer browses through a few projects, it’s very easy to get accustomed to this “custom” environment of Qt.


A Qt Project's Architecture

Every project consists of a “project” file with a “.pro” extension. This contains the general settings for the project and includes the names of all files that come along with the project categorized as Source files, Header files etc. If one creates a new Qt project without changing any default file names, then the project consists of a “main.cpp” file, a “mainwindow.cpp” file, a “mainwindow.h” header file and a “mainwindow.ui” file.
The “main.cpp” file just instantiates the QWindow class to create a new output window when the project is built and run. Then it transfers the control over to the “mainwindow.cpp” file which is the complete “brain” of the project. Any global declarations can be done in the “main.cpp” file with the extern keyword prefixed so that they can be accessed in every function (internal and external) of the “mainwindow.cpp” file. As every C++ programmer would guess, the “mainwindow.h” file has just has the declarations for every function, signal and slot defined in the corresponding .cpp file. The “signal and slot” mechanism of Qt is explained next.

All GUI development tools will have a mechanism to trigger a code based on an event that happens when the user interacts with the GUI. For Qt, this is the “signal and slot” mechanism. There are “signals” that the programmer define on specific events on different objects included in the GUI. While the events are defined by Qt, the signals to be “emitted” are defined by the user. These signals not only carry information defined in their code but also carry some sort of an encrypted code which will be used to authenticate the signal at its slot. The slot is again any function defined in any class of the project that is assigned to receive this signal using the “connect()” statement defined for every signal. Thus, any “emitted” signal can be defined to reach any “slot” which has the code to be performed corresponding to the event triggered by the user’s interaction. In a nutshell, this is what happens: the user clicks a button or hovers over a field or drags the scroll bar or does any such actions on an object in the GUI; this triggers a signal defined by the programmer for that event; the connect() statement directs the signal to the corresponding “slot”; the slot authenticates the signal with its code (which is not in the programmer’s control); then, it executes the code defined under it to produce a feedback for the user’s interaction.

On executing the “mainwindow.show()” in “main.cpp”, the code “MainWindow::MainWindow(QWidget *)” is first executed. Then, depending upon the flow of the code defined by the programmer, the other functions, signals and slots are executed. The “qDebug() << ” command can be used to find the state of the application anytime. The string to the right of the “<<” is output on the Qt Console (which is integrated with the Qt Creator tool itself).

The “mainwindow.ui” file defines the GUI completely. Qt Creator allows the developer to “drag and drop” GUI components directly and creates the corresponding xml file automatically thereby enabling the programmer to concentrate on improving the “working” of the application rather than spending an equivalent time on creating the GUI directly by tedious coding.

The QCustomPlot Library

The QCustomPlot library has extensive graphing capabilities which can be used to do almost everything that one wishes to see in a graph. It just contains a header named “qcustomplot.h” and a source “qcustomplot.cpp” which needs to be included in the project to be able to use it. Fortunately, it also comes with a lot of examples that demonstrate plotting of different type of graphs and also real-time ones. The complete documentation and downloads can be found at http://www.qcustomplot.com/index.php/introduction


PostrgreSQL and the QPSQL Plugin for Qt

PostgreSQL can be downloaded and installed for Windows from http://www.postgresql.org/download/windows/. It has its own GUI tool “pgAdmin” to enable easier interaction directly with the database. The installation directory has to be used next for QPSQL plugin. Prefer to download 32-bit version of PostgreSQL as it is not guaranteed that the QPSQL plugin can be built for the 64-bit version.

The next task is to be able to access the PostgreSQL database for which Qt needs a driver. The QPSQL driver is the one for this purpose and can again be integrated with Qt depending on whether Qt runs on the Visual Studio compiler or the MinGW compiler. Since the Qt project was installed to run with the MinGW compiler on Windows for this project, the steps to be followed to include the driver were followed as described in http://www.qtcentre.org/wiki/index.php?title=Building_the_QPSQL_plugin_on_Windows_using_MinGW

This is a straightforward process except when the versions of Qt mismatch with the one given in the link. In such case, change the “%QTDIR%” given in the webpage to be “C:\QtMinGW\Qt5.1.1\5.1.1\Src\qtbase” if the Qt installation directory is “C:\QtMinGW\Qt5.1.1”. Other than this, the installation of the QPSQL plugin is trouble-free.

I am giving an updated set of instructions (suitably modified from the above link) below for Qt 5.1.1 on Windows 7 (so that we are not lost if that link become invalid).

Throughout the instructions I will assume that the installation directory of Qt is "C:\QtMinGW\Qt5.1.1" and that of PostgreSQL is "C:\psql" (Mine is PostgreSQL 9.3). Suitably alter the instructions for yourself if your's is different. Thank you for the cooperation.


Pre-requisites for QPSQL Plugin

Make Tools

You need make tools if you are not using microsoft compiler. If make tools are not available already on your computer, download it from http://www.steve.org.uk/Software/make/. Extract it to a folder (preferably the C:\ drive directly and update your computer's PATH environment variable with this directory (which should be "C:\make\"). The necessary instructions are below.


Updating system's PATH Environment variable:

The following instructions are for Windows 7.
  1. Click on 'Start' and then right click on 'Computer'. Choose 'Properties' on the list.
  2. Click on the 'Advanced System Settings' tab on the left side.
  3. On the 'Advanced' tab in the pop-up window, click on the button 'Environment Variables' at the bottom.
  4. In the new window, scroll down the second list (for 'System Variables'), click on 'Path' and click on the 'Edit' button below.
  5. At the end of the 'Variable Value' box, insert a semi-colon (";") and copy the path of the folder that you want to update. (For the "make" folder described above, this should be "C:\make\" if you extracted the downloaded file there).

MinGW Utils:

Some of the tools required for the plugin installation (ex. the "reimp" tool) are not available with the QT 5.1.1 download. So, you will require to have mingw-utils which can be downloaded from the Source Forge website. 
Do NOT download mingw-utils-0.4 because it isn't working properly at least when I downloaded it.

Then, extract the folder somewhere and copy the contents of the "bin" folder in it to "C:\QtMinGW\Qt5.1.1\5.1.1\mingw48_32\bin".

("C:\QtMinGW\Qt5.1.1" is my installation directory for Qt)


Update PATH Variable for Qt and PostgreSQL:

Update the system's PATH variable (using instructions above) with the following string after adding a semi-colon (";") to the existing value):
"C:\PSQL\LIB\;C:\QTMINGW\QT5.1.1\5.1.1\MINGW48_32\BIN\;C:\PSQL\BIN\;C:\PSQL\INCLUDE\;C:\MINGW\BIN\"

Once again, this string is valid for me due to my installation directories of Qt & PostgreSQL. Change it according to your's.


QPSQL Plugin Installation

I am giving an updated set of instructions (suitably modified from the link http://www.qtcentre.org/wiki/index.php?title=Building_the_QPSQL_plugin_on_Windows_using_MinGW) below for Qt 5.1.1 on Windows 7 (so that we are not lost if this link become invalid).

Throughout the instructions I will assume that the installation directory of Qt is "C:\QtMinGW\Qt5.1.1" and that of PostgreSQL is "C:\psql" (Mine is PostgreSQL 9.3). Suitably alter the instructions for yourself if your's is different. Thank you for the cooperation.
  1. Open a Qt Command Prompt. Access it by: "Start->Qt 5.1.1->5.1.1->MinGW->Qt 5.1.1 for Desktop.
  2. Navigate to the PostgreSQL folder (which is "C:\psql\ for me) using the commands "cd" and/or "cd.."
  3. Go into the sub-folder "include" and open "pthread.h". Comment out lines 307-310 that contains definition for "struct timespec".
  4. Now, go into the sub-folder "lib" in "C:\psql\" and run the command "reimp libpq.lib" which will produce the files "liblibpq.a" and "libpq.def" in the same directory.
  5. Open this directory in windows explorer and then open the file "libpq.def" that just got created with the "Wordpad" application. In that, remove all the "_"s in the definitions whether the character (underscore) is present in the beginning or in the middle of any of the definitions in the file. Once done, check by performing a search for the "_" character and it should return no results. Close the file.
  6. Now, run the command "dlltool --input-def libpq.def --output-lib libpq.a --dllname libpq.dll" in the Qt command prompt. This is the import library to use with MinGW.
  7. Using the command prompt, navigate to the location "C:\QtMinGW\Qt5.1.1\5.1.1\Src\qtbase\src\plugins\sqldrivers\psql".
  8. Run the following command (with the quotes wherever present): 
  9. qmake -o Makefile "INCLUDEPATH+=C:\psql\include" "LIBS+=C:\psql\lib\libpq.a" psql.pro
  10. Run the command "mingw32-make" - this should build the "qsqlpsql.dll" and "libqsqlpsql.a" files in the "C:\QtMinGW\Qt5.1.1\5.1.1\Src\qtbase\plugins\sqldrivers" directory.
This should complete the plugin installation. Open a Qt Project and in the "main.cpp" file of the project, copy the following code and try running the project:
Before you run the project, open the ".pro" file of your project and do the following:
  • Find the line "QT + = core gui" and add "sql" to it to make it "QT + = core gui sql"
  • Find the line "QT + = widgets" and add "printsupport" to it (for 'qDebug' to work).
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    qDebug() << QSqlDatabase::drivers();
    return a.exec();
}

The output in the "Application Output" window should be:
("QSQLITE", "QODBC3", "QODBC","QPSQL7","QPSQL")

Last Step:

Unfortunately, for all your Qt projects that use PostgreSQL, you need to copy the following files from the directory: "C:\psql\bin\" to each of those project folders.

"libeay32.dll", "libiconv.dll", "libintl.dll", "libpq.dll", "ssleay32.dll"

If this isn't required, kindly comment below the alternative.

That's it! You can now access your PostgreSQL database from your Qt project. Refer to online sources for various commands associated with the QPSQL plugin for PostgreSQL.
I hope this helps and it works!

1 comment:

  1. If you are intersted in using Qt with PostgreSQL then you should try Sohag Developer
    you can download it from http://sohag-developer.com/download

    ReplyDelete