Advertisment

Coding GUIs in Linux

author-image
CIOL Bureau
Updated On
New Update

By: Ankit Khare

Advertisment

GUI programming for Linux has traditionally been a difficult task. Trolltech

has changed all that by introducing Qt, a platform-independent Object-oriented

library, that allows programmers to create GUIs easily. The Qt library allows

components of the GUI to interact with each other elegantly by using slots and

signals. Qt is in its third avatar, meaning v3.0, and is now a mature library.

It has even branched off as Qtopia, for development of GUI in embedded systems.

The Qt development kit is available commercially for nearly every platform,

including the Mac. For Linux it's under L'GPL. 

We'll talk about how to use Qt by building a basic graphical frontend for

mpg123, a popular command line MP3 player for Linux, using C++. Extensions are

also available for using the Qt library in Perl or Python programs. To get

started, install Qt development libraries from your Linux installation CD.

It's not installed by default. You'll find them in PCQ Linux 7.1 CD2 in the

RPMs folder with file names qt-designer and qt-devel.

Hello Qt 



To begin on any programming odyssey, a Hello world program is necessary. So,

let's see how to write one in Qt. Simply put the following script in any text

editor and save it in a separate directory. 

Advertisment

#include



#include


int main( int argc, char **argv )


{


QApplication a( argc, argv );


QPushButton hello(“Hello world!”, 0 );


hello.resize( 100, 30 );


a.setMainWidget( &hello );


hello.show();


return a.exec();


}








Now for compiling the code we have to take care of the following three steps. 

  • Create the project file using the qmake —project
  • Type qmake at the command prompt to create the makefile
  • Compile the source code with the make command. If all your libraries are

    installed correctly, an executable file of the same name as the directory

    will be created. Execute to see your very first Qt program work. 
Advertisment

In the program above, the qapplication header file has the definition of

QApplication class, which is the single most important class in any Qt

application. All Qt applications are instances of this class. The main function

parameters (argc & agrv) are passed to the constructors when creating an

object of this class. QPushButton is a simple push button, which is instantiated

as hello in this example. Two arguments are passed, first the label or the text

to be written on the button and the other a number identifying the parent window

(0 in this case). hello.resize(100,30) is self explanatory. QApplication object

allows us to set a main widget. If the main widget is killed somehow, the

application dies. This is done through a.setMainWiget(&hello).

hello.show() is akin to the VB's visible property. It does nothing but make

the component visible. exec() executes in a loop and passes all events to the

respective components of the GUI. This executes until the application closes or

is explicitly killed.

You

use slots and
signals to add

functionality to the interface
Advertisment

Next step



Now that we have got our feet wet, its time to create a more complex GUI,

which is a very basic frontend for mpg123. We have given the associated source

code for this on our CD in the source code section. In this article, we'll

explain the main elements of the code. 

For building the GUI we will use Qt designer for designing the frontend. Fire

up the designer from the command line by giving the designer command or use the

link in the Start Menu. Go to File menu and choose new, which will open a dialog

box asking for file type to be created. Choose dialog and press OK. You will now

see a VB style form on which you can add various components (widgets), just as

you do in VB. For the present context we will restrict ourselves to three types

of widgets: push button, pixmap and a dial. Now, create a simple form by

dragging and dropping the widgets.

This will serve as the GUI for your MP3 player. Save the form you've

created, and the Qt designer will output it as an XML based .ui (user interface)

file. We've given the .ui file for it on the CD. You can preview this

interface using the preview option from the menu. The pixmap label is used to

show the image. Once the interface is done, we have to add functionality to it.

This is where slots and signals come into play. Qt component widgets emit

signals when events occur. For example, a button will emit a 'clicked'

signal when it is clicked. The programmer can choose to connect to a signal by

creating a function (called a slot) and calling the connect () function to

relate the signal to the slot. This can also be done directly in Qt designer

(see picture on the right). 

Advertisment

To create the slots, we use the Edit->slots option. Add five slots

fileplay(), filestop(), bye(), volume(int) and filechange() for the five basic

operations in the MP3 player, namely play, stop, quit, change volume and change

song. For connecting slots and signals, the Qt designer provides a very

intuitive method. Press F3 and select the widget emitting the signal and drag

the mouse to the empty space in the form. A dialog window will pop and associate

the required signal to one of the slots. In this fashion associate clicked

signal of each of the push buttons to the four slots (file). Associate the

valueChanged(int) signal of the dial to the volume(int) slot. The valueChanged

signal is emitted whenever the dial is moved. The label on the buttons and the

caption on the windows can be changed from the property editor accessible from

window->view->property editor. After doing all this cosmetic work it's

time to write the actual code. The user interface file is used by uic (user

interface compiler) to generate the corresponding c++ code. This is taken care

of in the makefile generated by qmake in the second step of compiling the Qt

code. So, any modifications to this c++ code will get erased, therefore, more

functionality is added by sub classing. Let's see how this is done. 

We created slots for the main form, hence we would be sub classing the same.

We named the Main Form as MP3. We now create a file mp3_player.h having the

definition of the new sub class mp3_player. The c++ code for this is as follows. 

#ifndef MP3_PLAYER_H



#define MP3_PLAYER_H


#include “mp3.h”


class mp3_player : public MP3


{


Q_OBJECT


public :


mp3_player( QWidget* parent = 0, const char* name = 0, bool modal = FALSE,
WFlags f = 0 ) : MP3( parent, name, modal, f ) {}



public slots :


virtual void fileplay() ;


virtual void filechange();


virtual void filestop();


virtual void volume(int a);


virtual void bye();


} ;


#endif













Advertisment

Q_OBJECT is used by moc, Meta Object Compiler during the compilation process.

“public slots” are now added using the virtual specifier.

Now let's create the mp3_player.cpp file, which will contain the functional

code. This will contain the code for all the slots. Here, we'll explain two of

them, namely filechange() and fileplay(). The remaining slots are similar to the

filechange() function.

void mp3_player::filechange() {



s = QFileDialog::getOpenFileName(


“/” , “Audio files (*.mp3)” ,


this ,


“open mp3 file “


“choose your mp3” );


}




Advertisment

In the above code, s is a QString type global variable

in which the filename is stored. This is done by calling the static method

getOpenFileName() of the QFileDialog class. The code for fileplay() will be as

follows. 

void mp3_player::fileplay() {



QMessageBox::information ( this , “Now Playing “ , s , QMessageBox::Ok ) ;


QString play(“mpg123 “);


QString file=play+”'”+s+”'”+”&” ;


system(file.latin1());


}



In this the variable 's' from the filechange() function is used to create

a command line argument for mpg123 and finally mpg123 is executed using the

system() call. 

The working of another slot, namely the volume(int a) is similar to the

fileplay() function, where the dial position 'a' is used to generate

arguments for aumix (audio mixer for Linux) used for controlling the volume. 

After all this, we have to write the main.cpp file, similar to the hello

world code, where the main widget is an instance of the mp3_player class.

Compile the code as we explained above. There is one quirk in the program. If

the player is killed explicitly (using a kill command or from the X button), the

song doesn't stop playing. This is because the mpg123 is run as a separate

program in the background and not as a child process. We'll leave the solution

to this to you as an exercise.

Source: PCQuest

tech-news