2008-10-24

#pragma once

As promised, the next part of my coding in Linux guide. Last time i covered my choice of IDE, and now i'm gonna use it. My intent was to work with Open GL, and that will come in time, but after some research it seems that my blog is more popular amongst KDE users. So, this is the plan. A basic QT app, with Open GL included somewhere :)

In Codeblocks there are many project options. Making sure that you already have qt4-devel packages installed, create a new QT4 project. It'll probably ask for an Environment variable path. Define the Base to /usr and that should be it. Then Codeblocks will hopefully give you a main.cpp containing the basic QT setup. Running this app should give a simple window with a Quit button.

QT reference/tutorials can be found here, its a great thing to keep open if u'r coding an app and your main aim isn't the UI. After all thats why i prefer QT, it lets me focus on my app and not have to deal with really disgusting UI code ( note GTK and Win32 ). In QT there are 2 constructs which you probably won't have seen outside of QT code:

  1. SIGNAL: a sort of event triggered, like clicked() or valueChanged() or anything you want.
  2. SLOT: a response for a signal.

To make use of the SIGNAL/SLOT features of QT, make your object inherit from QObject ( directly or indirectly ) and add Q_OBJECT right at the top of the class declaration ( just after the opening brace ). Then you have access to the slots and signals macros which can be used in an equivalent way to private and public. You also have access to the emit keyword, which allows your app to send a signal to whoever might be listening.

So, time to actually do something.

In Codeblocks, create a new file, selecting a C++ header. Once you've given it a name ( and path ), you'll see that Codeblocks auto generates a header guard word! Note that although usage of #pragma once is pretty standard, it isn't actually in the C++ specification, so it doesn't have to work. Click All on this dialog to add you're new header to all build targets ( another thing i love about Codeblocks, build target config is really simple ). Create this, and create a cpp in a similar way. I made a basic QT app:

myApp.h
#ifndef MYAPP_H_INCLUDED #define MYAPP_H_INCLUDED #include ; class myApp : public QObject {   Q_OBJECT public:   myApp( QObject* parent );   ~myApp(); public slots:   void updateColor( int newValue ); signals:   void colorChanged( int newValue ); private:   unsigned int m_red;   unsigned int m_green;   unsigned int m_blue; }; #endif // MYAPP_H_INCLUDED
myApp.cpp
#include "myApp.h"

myApp::myApp( QObject* parent )

:

QObject( parent ) {   printf("Creating myApp\n"); } myApp::~myApp() {   printf("Killing myApp\n"); } void myApp::updateColor( int newValue ) { }
Now this will not compile ( sadly ). Due to the way QT works, you need to perform a meta-object compilation, using the moc tool. If you look in your project's Build Options, under Pre/Post build steps, we can add custom commands. I added a script to my projects root folder ( called runMoc.sh ), and added the following to the custom commands:
./runMoc.sh
The contents of my script is:
#!/bin/sh grep -l Q_OBJECT *.h > files_to_moc cat files_to_moc | while read line do   echo "Moc'ing file $line";   ext=h   output=${line%h}   moc $line -o "moc_$output""cpp" done
Although the details don't really matter, the script basically finds all .h files with Q_OBJECT in them and calls moc on them. Then the moc call generates a new cpp called moc_.cpp. Now if we do a build, it will run moc on our file and create this new cpp ( and give build errors ). Add this new cpp ( in my case, moc_myApp.cpp ) to the project ( remember to put it in both Debug and Release targets ), and build again! This time, no errors. If we add anymore Q_OBJECT files, all we have to do is add the build generated cpp to the projet. I realise it's a bit annoying having to add the cpp to the project every time we add a new file ( and trust me, i'm looking for a better way of doing this ), but its better than learning about Makefiles! Other IDE's like KDevelop ( and presumably the new QT IDE ) will do these things automatically, but then you wouldn't get all the cool other features Codeblocks gives you.Since this has become a really long article ( mostly due to the code inserts ), i'm going to cut it here. Now we know how to set up a QT project and use the cool features, so next time we should actually do something with them.

1 comment: