Tuesday, November 23, 2010

Using qmake from WinXP Command Line

qmake is used to create Makefiles from .pro files for QT projects.
qmake uses what you put in your project (.pro) files to decide what should go in the Makefiles it produces.

In order to test your installed qmake version type:
C:\>qmake -v
from command line but it produces an error message like:
'qmake' is not recognized as an internal or external command,
operable program or batch file.

In order to use qmake from winXP command line set following variables:
1-) Set the QMAKESPEC environment variable to point to a directory containing a description of your platform and compiler
2-) Add the 'qmake' executable to your PATH

I have installed QT4.6 at C:\Qt\4.6.0 , it can be at a different location on your disk. Execute following commands from command line respectively:

C:\>set QMAKESPEC=C:\Qt\4.6.0\mkspecs\win32-msvc
C:\>set PATH=%PATH%;C:\Qt\4.6.0\qmake

And then to check it type following.

C:\>qmake -v
QMake version 2.01a

Now you can use qmake to generate Makefiles from your .pro files.

Monday, October 25, 2010

Log Time, Date, FileName, FunctionName, LineNumber for QT Applications in C++

Logging provides developers with detailed information about program flow. Logging also makes tracing of exceptions occured easier at run-time. By including date, time, filename, functionname, linenumber into a text file; it becomes a helpful guide for program flow trace. C++ comes with macros that are usable for logging purposes.
"__FILE__" macro gives information about the curent fileName and returns a string. "__FUNCTION__" macro gives information about the name of the current function and returns a string. "__LINE__" macro gives information about the current line number and returns an integer value. These are ANSI-Compliant Predefined Macros.
Logger.h file contains declaration for Log class.
#include <fstream>
#include <QString>
using namespace std;

class Log {
public:
 Log();
 ~Log();
 void trace(QString fileName, QString functionName, int lineNumber);
private:
 ofstream myFile;
 char stime[9];
 char sdate[9];
};


Logger.cpp file contains implementation for Log class. trace() method takes fileName, functionName and lineNumber as parameters.
#include <fstream>
#include "Logger.h"
#include <time.h>
using namespace std;

Log::Log() {
}

void Log::trace(QString fileName, QString functionName, int lineNumber) {
 _strtime(stime);
 _strdate(sdate);
 myFile.open("C:\\example.txt", fstream::in | fstream::out | fstream::app);
 myFile<<"Date:"<<sdate<<";"<<" Time:"<<stime<<";"<<" FileName:"<<qPrintable(fileName)<<";"<<" FunctionName:"<<qPrintable(functionName)<<";"<<" LineNo:"<<lineNumber<<endl;
 myFile.close(); 
}

Log::~Log(){
 myFile.close();
}


main.cpp file uses Log class trace method for logging purposes.
#include "logger.h"
int main(int argc, char *argv[])
{
   Log* logger = new Log();
   logger->trace(__FILE__, __FUNCTION__, __LINE__);
   return 0;
}


trace method produces the output to the example.txt file that is located under the c:\ root directory. Sample output is generated as follows:
Date:10/25/10; Time:21:07:25; FileName:.\main.cpp; FunctionName:main; LineNo:5

Tuesday, October 19, 2010

Type of Custom QGraphicsItem on the QGraphicsScene

Applications that contain different kinds of derived QGraphicsItem instances need to identify that instances to achieve different operations on them at runtime.
"int QGraphicsItem::type() const [virtual]" method of QGraphicsItem class enables the clients to check for the type of the custom QGraphicsItem. Each unique QGraphicsItem instance returns a unique integer value from the type() method.
For custom QGraphicsItem classes it is also required to implement
"QRectF QGraphicsItem::boundingRect(void) const"
and
"void QGraphicsItem::paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*)"
methods additionally.

"CustomGraphicsItems.h" file contains TextItem and LineItem class definitions.
#include <QGraphicsItem>
class TextItem : public QGraphicsItem {
public:
 enum { Type = UserType + 1 };
 int type() const { return Type; }
 TextItem(QGraphicsItem* parent = 0 );
 ~TextItem();
protected:
 void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = 0 );
 QRectF boundingRect() const;
};
class LineItem : public QGraphicsItem {
public:
 enum { Type = UserType + 2 };
 int type() const { return Type; }
 LineItem(QGraphicsItem* parent = 0);
 ~LineItem();
protected:
 void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = 0 );
 QRectF boundingRect() const;
};

Each custom QGraphicsItem instance is uniquely identified in the enum .

"CustomGraphicsItems.cpp" file contains implementation for TextItem and LineItem classes.

#include "CustomGraphicsItems.h"
TextItem ::TextItem(QGraphicsItem* parent) : QGraphicsItem(parent) {}
TextItem::~TextItem() {}
QRectF TextItem::boundingRect() const {
 return QRectF();
}
void TextItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {}
LineItem ::LineItem(QGraphicsItem* parent) : QGraphicsItem(parent) {}
LineItem::~LineItem() {}
void LineItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {}
QRectF LineItem::boundingRect() const {
 return QRectF();
}

"CustomScene.h" file contains derived QGraphicsScene class.
#include <QGraphicsScene>
class CustomScene : public QGraphicsScene {
public :
 CustomScene(QObject * parent = 0);
 ~CustomScene();
};

"CustomScene.cpp" file contains implementation for derived QGraphicsScene class.
#include "CustomScene.h"
CustomScene::CustomScene(QObject * parent) : QGraphicsScene(parent) {}
CustomScene::~CustomScene() {}

"CustomMainWindow.h" file contains definition for derived QMainWindow class.
#include <QMainWindow>
class CustomScene;
class CustomMainWindow : public QMainWindow {
public:
 CustomMainWindow(QWidget *parent = 0);
 ~CustomMainWindow();
 void displayItemType();
 void addItemsToGraphicsScene();
private:
 CustomScene* customScene;
};

"CustomMainWindow.cpp" file contains implementation for derived QMainWindow class.
#include <QDebug>
#include "CustomMainWindow.h"
#include "CustomScene.h"
#include "CustomGraphicsItems.h"
CustomMainWindow :: CustomMainWindow(QWidget *parent) {
 customScene = new CustomScene(this);
 addItemsToGraphicsScene();
 displayItemType();
}
void CustomMainWindow :: addItemsToGraphicsScene() { 
 TextItem* textItem = new TextItem();
 customScene->addItem(textItem);
 LineItem* lineItem = new LineItem();
 customScene->addItem(lineItem);
}
void CustomMainWindow :: displayItemType() {
 QList<QGraphicsItem*> itemList = customScene->items();
 for(int i=0; i<itemList.size(); i++){
  if(itemList[i]->type() == TextItem::Type )
   qDebug() << "I am TextItem";
  else if(itemList[i]->type() == LineItem::Type)
   qDebug() << "I am LineItem";
 }
}
CustomMainWindow :: ~CustomMainWindow() {}

"Main.cpp" file contains an instance of CustomMainWindow class. CustomScene is the container for the TextItem and LineItem instances and it is initialized in the CustomMainWindow constructor. addItemsToGraphicsScene() method of CustomMainWindow adds TextItem and LineItem instances to the CustomScene.
Types of custom QGraphicsItem instances are checked in displayItemType() method of CustomMainWindow class.
#include <QApplication>
#include "CustomMainWindow.h"
int main(int argc, char *argv[])
{
 QApplication app(argc, argv);
  CustomMainWindow* cm = new CustomMainWindow;
  delete cm;
 return app.exec();
}


Tested with MSVS2008 and QT4.6.0

Wednesday, September 29, 2010

Convert int to QString

Qt's QVariant helps to convert an integer value to a QString.

toString() method of QVariant returns the variant as a QString, if the variant has type() Int.

Also, QString's number(long x) static method returns a string equivalent of the numeric value of x.

Following example converts a given integer value to QString by using QVariant. And also it creates integer value from QString by using QString::number() static method :


#include <QVariant>
#include <QDebug>
int main() {
    // use QVariant
    int x = 12;
    QVariant var(x);
    QString stringValue = var.toString();
    qDebug() << "String to print-1 :"+stringValue;
    //use QString::number(long n, int base = 10)
    QString stringValue2 = QString::number(x);
    qDebug() << "String to print-2 :"+ stringValue2;
    return 0;
}


When the main method runs following terminal output is generated :

"String to print-1 :12"
"String to print-2 :12"

Sunday, September 26, 2010

error: ‘cout’ was not declared in this scope

When using cout and cin for standard output and standard input purposes without "using directive", compiler generates an error message about undeclared cout and cin. In order to get rid of this error message, it is required to add "using namespace std" using directive at a new line.
App.cpp file
#include "App.h"
#include <iostream>
using namespace std;

void App::HelloWorld(){

    cout << "Hello World";
}

In addition to #include <iostream> preprocessor directive, insertion of "using namespace std" helps to compile successfully.

Tuesday, July 13, 2010

Forward declaration vs #include directives

Using forward declaration of C++ classes in header files decreases total compilation time of the application and lowers dependencies. This also makes application easier to modify. It is suggested that when it is necessary to use #include directives, use it. But also avoid usage of unnecessary #include directives and replace them with forward declaration in the header file. Some basic rules that I obey most of the time when using #include directives and forward declarations are as follows:
#include directive :
- Use in both .h header file and implementation file
- Base classes are introduced by using include directives

forward declaration :
- Use in .h header file
- Pointer return values and method parameters can be forward declared

Sample.h file :
//include directive for base class
#include "BaseItemEntity.h"
//forward declaration for method parameters and return values
class QString;
class Item;
class ItemBody : public BaseItemEntity
{ 
public:
 QString getItemID();
 Item* getItemByName(QString&);
};

Sample.cpp file :
#include "Sample.h"
#include "Item.h"

QString ItemBody::getItemID()
{
 return QString();
}

Item* ItemBody::getItemByName( QString& name)
{
 Item* item = new Item(name);
 return item;
}


There is also a useful c++ coding guide that is giving clues for header file dependencies at this link

Friday, July 9, 2010

static const QString

Java allows to define constant Strings as
public final static String SIZE = "size";
in your .java files.

To define static const QString members for a class in c++ environment,
put your static const QString member into related .h file.
Constants.h
class QString;
class Constants{
public:
 static const QString xmlBaseFolderPath;
};

Add related initialization of the static member into .cpp file.
Constants.cpp
#include "Constants.h"
#include <QString>
const QString Constants::xmlBaseFolderPath = "C:\\XML";

Wednesday, June 30, 2010

Get list of XML files from specified directory. QStringList,QDir,QRegExp

QStringList can be used to store the list of names of xml files which are in a directory. Following method returns the list of names of files matching the regular expression.
QStringList XMLReader::getListOfFiltersFromDirectory()
{
    QDir directory = QDir("C:\\filters");
    QStringList listOfFilters = directory.entryList(QDir::Files | QDir::NoSymLinks);
    QRegExp rx("*.xml");
    rx.setPatternSyntax(QRegExp::Wildcard);
    listOfFilters = listOfFilters.filter(rx);
    return listOfFilters;
}

Saturday, April 17, 2010

Installing Fast Debugger for NetBeans 6.8 on Ubuntu 9.10

NetBeans IDE enables RoR developers to set break points in specific parts of source files. It is time consuming to use print statements to trace application development process. Because Fast Debugger uses native C extensions, gcc and some other extra packages need to be installed on your Ubuntu 9.10:

$ sudo apt-get install build-essential autoconf

Above command installed the following extra packages :
automake autotools-dev dpkg-dev fakeroot g++ g++-4.4 libstdc++6-4.4-dev m4
patch

Now you need to install ruby1.8-dev package to compile any native extensions.

$ sudo apt-get install ruby1.8-dev

Above command installed ruby1.8-dev package.
Now the ruby-debug-ide gem should build successfully.

$ gem install ruby-debug-ide
Building native extensions. This could take a while...
Successfully installed ruby-debug-ide-0.4.9
1 gem installed
Installing ri documentation for ruby-debug-ide-0.4.9...
Installing RDoc documentation for ruby-debug-ide-0.4.9...

NetBeans automatically detected Fast Debugger.$ gem list

*** LOCAL GEMS ***

actionmailer (2.3.4, 2.3.2)
actionpack (2.3.4, 2.3.2)
activerecord (2.3.4, 2.3.2)
activeresource (2.3.4, 2.3.2)
activesupport (2.3.4, 2.3.2)
linecache (0.43)
rack (1.0.1)
rails (2.3.4, 2.3.2)
rake (0.8.7)
ruby-debug-base (0.10.3)
ruby-debug-ide (0.4.9)