Apr 13

I shall start with a brief intro on Qt’s theming/styling and different ways they can be controlled at run-time and go through with some example and references:

Look and feel (theme) of Qt applications can be changed either by implementing custom style class inherited from QStyle or by using one of the predefined Style classes supplied with Qt. For example you can set your applications theme to Motif by calling
qApp->setStyle(new QMotifStyle);
Here QMotifStyle comes inbuilt with Qt.
You also can create your custom theme by deriving from one of the predefined style classes and overriding the virtual methods like drawPrimitive(..) accordingly. More detailed discussion on the same can be found here,
http://doc.trolltech.com/4.6/style-reference.html

A sample example is also supplied with Qt installation at \examples\widgets\styles (http://doc.trolltech.com/4.6/widgets-styles.html)

While the above method allows us to change theme at runtime and the custom style class to be statistically linked with the application during build. There is also a way we can implement the custom style as Qt plugin and place it under \plugins\styles folder so that the style can be loaded at runtime and is available to any arbitrary Qt based application.
We can set this theme to any qt application by passing a command line argument like this,
Myapplication.exe –style custompluginstyle
The application will use the look and feel from the custom style you implemented.

Along with what’s possible by subclassing QStyle, there is another robust way of controlling your applications s look and feel using stylesheets which are very similar to HTML CSS. For example we can change theme of all buttons by doing like this,
QPushButton {
border: 2px solid #8f8f91;
border-radius: 6px;
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #f6f7fa, stop: 1 #dadbde);
min-width: 80px;
}

QPushButton:pressed {
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #dadbde, stop: 1 #f6f7fa);
}

QPushButton:flat {
border: none; /* no border for a flat push button */
}

QPushButton:default {
border-color: navy; /* make the default button prominent */
}

Similarly we can change style of almost all the widgets and keep all of them in a qss file which can be loaded later at runtime like this,

QFile file("");
file.open(QFile::ReadOnly);
QString styleSheet = QLatin1String(file.readAll());

And do call QApplication::setStyleSheet(..) ,
qApp->setStyleSheet(styleSheet);

More detailed discussion on stylsheets can be found here, http://qt.nokia.com/doc/4.6/stylesheet.html

Another interesting discussion on this topic here,
http://doc.trolltech.com/qq/qq09-q-and-a.html

Mar 15

I was trying to do image manipulation like rotate/resize/convert image files. My application is a daemon running in the background various kind of services. While Qt’s QImage class provides robust functionality and is well enough to do image manipulations, problem here was the size of QtGui module which is around 7 Mb. I don’t like to load 7Mb of binary to memory for just few functions in QImage.

Cocoa’s NSImage seems the right candidate for such requirements.
For example, the following simple code does image resizing,

NSBitmapImageRep *rep = [NSBitmapImageRep imageRepWithData:srcData];
NSImage *scratch = [[[NSImage alloc] initWithSize:NSMakeSize(100, 100)] autorelease];
[scratch lockFocus];
[[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh];
[rep drawInRect:NSMakeRect(0.0, 0.0, 100, 100)];
NSBitmapImageRep *output = [[[NSBitmapImageRep alloc] initWithFocusedViewRect:NSMakeRect(0,0,100,100)] autorelease];
[scratch unlockFocus];

One important point to note in the above code is if you are trying to do lockFocus inside a Qt Core application(non-gui application), the lockFocus will throw an exception and results in application crash if unhandled.
Solution to this is to call NSApplicationLoad() inside main() or any place before you call lockFocus. This is required (or a call to [NSApplication sharedApplication]) for our application to have a window server connection for the lockFocus to work.

And the following single line of code would convert to any arbitrary format,

NSData *bitmapData = [output representationUsingType:NSJPEGFileType
properties:nil];

Tagged with:
Mar 03

At last I am able to beat my procrastination and decided to start something like sharing knowledge to others through this blog. Why not I could start with Qt? I too am new to this cute technology, so I thought it would be great idea to share what I do to get mastered in Qt with fellow Qt learners ;-)

Let’s get started by setting up the development environment. It is very simple,

1 ) Download latest Qt SDK from trolltech site (Now QT Software after Nokia Acquire). Here is direct link for Windows SDK,

http://www.qtsoftware.com/downloads/sdk-windows-cpp

Install the SDK to something like C:\Qt\ or just leave the default install path as it is.

2) [Optional] This step is required if you want to use Visual C++ express edition as IDE for building Qt apps. I would recommend to use VC++ editor, I found it very powerful and lot easier to develop. Otherwise QT Creator will just do the job!. Get latest VC++ express version from here,

http://www.microsoft.com/express/vc/

This download includes Platform SDK aswell if it is VC++ 2008 or greater

Follow the installation wizard and finish installation

3) set environment variable PATH to qt’s bin directory. For example mine is

PATH=”\Qt\2009.02\qt\bin;\Qt\2009.02\bin”

4)Now configure qt for the target development platform. You can do this by launching VC++ command prompt and running thiscommand,

configure -platform win32-msvc2008

this step will vary if you use other IDE other than Visual Studio.

5)Here comes the final step, change to \qt\2009.02\qt directory and run nmake and grab a cup of coffee as this is going to take a while to finish. My machine with 2 processors (2.6GHz) took 2 hours :)

Bingo! your development environment is now set, you can right away start building Qt apps at this point (Of course if you know how to :P )

Hello World!

Hey whats a getting started guide without a “Hello World!” app! Here is one written in Qt,

#include <QtGui>

int main(int argc, char *argv[])
{
 QApplication app(argc, argv);

 QLabel label(“Hello World!”);
 label.show();

 return app.exec();
}

create a file called main.cpp and copy/paste above code. Create platform independent project file by running “qmake -project” in the directory where you placed main.cpp. Generate VS project file by running “qmake -tp vc” which will create *.vcproj file which you can use further to build and work on this app from VS IDE.
Build the application in Visual Studio, the resulting program will look something like this on Win XP,

Hello World in Qt

Hello World in Qt

Let’s get started!

Now we shall get started and write something simple and cool. To make it interesting I will do a “screen shooter” application which will basically simulate a shooting effect on mouse click into your desktop screen :D

The idea is grab an image of current desktop in full screen, listen for mouse press event, draw a burn image where the mouse was pressed, play an explode sound to get a feel we shot ;)

Here we go,

1) Get a screenshot of the entire desktop, this is how we can do in Qt,
QPixmap pixmap = QPixmap::grabWindow(QApplication::desktop()->winId()); 

QPixmap is a Qt class which makes it easy to deal with image data. Find more info here, http://doc.trolltech.com/4.5/qpixmap.html

2) Listen for mouse press event and store the coordinates when a click is made,

void ScreenShooter::mousePressEvent(QMouseEvent *event) //QWidget’s virtual method
{
 currentClickedPos = event->pos();

}

3)simulating the shot!, draw the things on the screen using QPainter like this,

QPainter painter(this);
 
painter.drawPixmap(0, 0, QPixmap::grabWindow(QApplication::desktop()->winId()));
painter.drawImage(currentClickedPos – QPoint(20, 20), QImage(“:/explode.png”));  //explode.png is 40×40, so the magic offset point (20, 20) :D

4) You can play sound in Qt with QSound as simple as like this,

QSound snd(“resources/Explosion.wav”);
snd.play();

Seems like QSound can play only wav files as of Qt 4.5

5) Putting the pieces together,

void ScreenShooter::paintEvent(QPaintEvent* event)
{
 QPainter painter(this);
 
 painter.drawPixmap(0, 0, QPixmap::grabWindow(QApplication::desktop()->winId()));
 painter.drawImage(currentClickedPos – QPoint(20, 20), QImage(“resources/explode.png”));
}

void ScreenShooter::mousePressEvent(QMouseEvent *event)
{
 currentClickedPos = event->pos();

 update();

 QSound snd(“resources/Explosion.wav”);
 snd.play();
}

 Screen shooter running on my machine…

screen_shooter2

The explode watermark image doesn’t look great, could be made more natural :P

Thats all folks for now!

Keep checking for more advanced experiments in my next post.

Tagged with:
preload preload preload