" Dont judge those who try and fail, judge those who fail to try "

Beginning KDevelop Programming Version 3.x

Chapter One :- Introducing KDevelop Chapter Two :- The KDE Application Chapter Three :- Common Widgets Chapter Four :- Containers And Views Chapter Five :- Database Programming With MySQL Chapter Six :- Input And Display Chapter Seven :- KDE Display Widgets Chapter Eight :- KDE Buttons And Input Chapter Nine :- KDE Containers And Views Chapter Ten :- Custom Widgets Chapter Eleven :- Events Chapter Twelve :- Drawing Chapter Thirteen :- Global Information and Configuration Files Chapter Fourteen :- A Simple Editor Application

Appendices

Appendix A :- Upgrading KDevelop

Downloads

PDF

Beginning KDevelop Programming ( 13.4 mb )

ZIP

Chapter One Source ( 1.2mb ) Chapter Two Source ( 3.8 mb ) Chapter Three Source ( 6.9 mb ) Chapter Four Source ( 6.4 mb ) Chapter Five Source ( 6.6 mb ) Chapter Six Source ( 3.6 mb ) Chapter Seven Source ( 2.2 mb ) Chapter Eight Source ( 2.2 mb ) Chapter Nine Source ( 1.1 mb ) Chapter Ten Source ( 5.3 mb ) Chapter Eleven Source ( 1.6 mb ) Chapter Twelve Source ( 5.2 mb ) Chapter Thirteen Source ( 3.8 mb ) Chapter Fourteen Source ( 616 kb )

Contributions

Contributors Page

Contacts

Author

[email protected]

Page Designer

[email protected]

Chapter 7 :- KDE Display Widgets

From this point onwards all the widgets we use will be part of the KDE system which means unlike a lot of the code that we have seen to date which relies largely on Qt the following code will require KDE to be installed if it is to run on any Linux system.

The Display ( KDE ) section looks like,


The first section that you will notice from the picture is the KPartsGenericPart widget. This widget takes us places that are beyond the scope of this book and into far more advanced topics than we are ready for. If you wish to know about this widget look up Chapter 12 of the KDE2 Development Book in the help.

KDE Display

The first example that we look at in the KDE Display section is a slight modification of what we have seen before and uses the KTextBrowser, the KProgress bar and the KLed displays as well as some of the common dialogs that we saw earlier,


As you can see with the exception of the KLed lights to represent the file properties and the KProgress bar across the bottom the application is almost identical to the one we saw earlier.

The main difference between the KTextBrowser and the QTextBrowser that it extends is the handling of web links like,


so although the display above will appear identical in both the QTextBrowser and the KTextBrowser if you click on one of the links in a running KTextBrowser then the default web Browsing application on your system will open the page.

The Buttons for the Font, File and Colour start the standard dialog boxes that we have seen earlier in fact the code is pretty much a direct cut and paste of the previous code.

The KLed widget represents and Led light switch that we are using here to affirm if the file status corresponds to the above text. The KLed will be bright green if true and dark green if it is false. The KLed's are set with the following code,

QFileInfo fileInfo( kurl.pathOrURL() );
        
if( fileInfo.isSymLink() == true )
{
   linkLED->setState( KLed::On );
}
else
   linkLED->setState( KLed::Off );

We get a QFileInfo from the KURL and then test it's state and set the KLed appropriately.

The KProgress widget is derived from the QProgressBar that we saw earlier and the only differences are the way in which it sends signals when changes are made which will not usually make any difference to standard operation unless you want to change things based on the percentage of completion of the progress bar.

The only difference in our code is that the progress bar does work better than it did in the previous example but this is because I do this,

// get the number of lines in the file
        
nNumberOfLines = 0;
if( file.open( IO_ReadOnly ) == true )
{
    QTextStream stream( &file );
    while( stream.atEnd() == false )
    {
       stream.readLine();
       nNumberOfLines++;
    }
                
    file.close();
}
        
progressBar->setTotalSteps( nNumberOfLines );

I run through the file and count the number of lines and then call setTotalSteps to the number of lines in the file. This gives the progress bar a definite number to aim for, making it more accurate.


The finished project looks like the above picture showing the application displaying it's own .moc file.

Tip Of The Day

Occasionally you may find that one of the widgets is not set up right automatically when you drop it on to the form. There are a number of these in the following examples so here is how you identify and fix the problem. When you drop a widget onto the form such as a KPaletteTable,


It looks fine but when you save the .ui file and compile you get,

chapterseventestwidgetbase.cpp: In constructor chapterseventestWidgetBase::chapterseventestWidgetBase(QWidget*, const char*, uint)’:
chapterseventestwidgetbase.cpp:51: error: invalid conversion from ‘const char*’ to ‘int’
chapterseventestwidgetbase.cpp:51: error: initializing argument 2 of ‘KPaletteTable::KPaletteTable(QWidget*, int, int)’

If we open the generated "projectname"widgetbase. h file the KPaletteTable is declared as

KPaletteTable* unnamed;

and in the generated "projectname"widgetbase.cpp file constructor the KPaletteTable is initialised as,

unnamed = new KPaletteTable( this, "unnamed" );
unnamed->setGeometry( QRect( 130, 100, 228, 153 ) );

As you can see from the above compiler print out the constructor is complaining about the second argument which is the "unnamed" text. If you want to you can delete this and check to see if the program is running properly but remember this is not a permanent solution as soon as you change the form this file will be regenerated and your changes will be lost. The permanent solution is to copy the code that sets up the offending widget into the "projectname"widget files so in order to get the KPatletteTable working we would add

class KPaletteTable;

before the class declaration and

public:
        KPaletteTable *paletteTable;

within the class file add the header for the class.

#include "kcolordialog.h"

and,

paletteTable = new KPaletteTable( this );
paletteTable->setGeometry( QRect( 130, 100, 228, 153 ) );

within the constructor. Of course this is going to make the layout of the widget form a complete pain so as you know where you want the offending widget to go, set a frame around that area and then you can adjust the layout of the widget as normal.

KDE Image Preview

For the second example in this chapter we mainly concentrate on the KImageFilePreview widget and then throw in a KURLLabel and a KActiveLabel more for good measure than for any specific purpose.


As you can see from the picture above there is no KImageFilePreview on the page this is because the generated code if we try to drop a KImageFilePreview widget on the form calls non-exsistent constructors so we use a standard QFrame as a place holder for the KImageFilePreview and implement it ourselves, as discussed in the Tip Of The Day section above. The two widgets below the Get File button are the KURLLabel and the KActiveLabel, these are used here as standard labels to show the path and filename of the file that we are previewing.

To set up the KImageFilePreview widget we add an object of the type into the header file for out implementation class which in this case is the file chaptersevenimagepreviewwidget.h and then in the constructor for the class we add

ChapterSevenImagePreviewWidget::ChapterSevenImagePreviewWidget(QWidget* parent, const char* name, WFlags fl)
        : ChapterSevenImagePreviewWidgetBase(parent,name,fl)
{
   pKImageFilePreview = new KImageFilePreview( this );
   pKImageFilePreview->setGeometry( QRect( 37, 10, 670, 388 ) );
   pKImageFilePreview->setMinimumSize( 630, 388 );
   imagePreviewLayout->addWidget( pKImageFilePreview );
}

Once the widget is created using it is fairly simple.

void ChapterSevenImagePreviewWidget::fileButton_clicked()
{
   KURL kurlFile = KFileDialog::getOpenURL();
        
   if( kurlFile.isEmpty() == true )
   {
      KMessageBox::error( this, "Error the file is empty, please choose another file" );
      return;
   }
        
   pKImageFilePreview->showPreview( kurlFile );
   QString string = kurlFile.pathOrURL();
   urlLabel->setText( kurlFile.pathOrURL() );
   activeLabel->setText( kurlFile.pathOrURL() );
}

We run a KFileDialog as seen previously to get the file and then pass the filename to the KImageFilePreview widget with a call to showPreview. Then we add the filename to the labels.

When the KFileImagePreview widget is running it has two modes the first which is the default is to display the preview of the file as soon as it is passed a filename,


If we uncheck the Automatic preview option the KImageFilePreview widget will wait until we click the Preview button before it displays the preview.


Once we have set the widget up and passed it a filename then there is nothing else for us to do as the widget takes care of the rest for us.

As for the labels the KURLLabel is a label with idea that we can use it to provide links to other web pages or files by simply clicking on it, although the handling of this is left up to us and is not implemented here, but it means that by default the label changes colour when the mouse is hovered over it indicating that it is an active widget ready for use.


The KActiveLabel widget is a different implementation of the same idea although it doesn't give the same visual clues it does have an openLink function that can be called with the file name.

KDE Animation

The next example just looks at the KAnimWidget which is included in the Display ( KDE ) section of the Toolbox.

The setup of the project looks like this,


As you can see there is no widget viewable on the form which means that the drag and drop aspect of KDevelop adds the wrong constructor again so we set up as with the other widgets seen previously and add the code,

pAnimWidget = new KAnimWidget( "kde", 0, this, "kAnimWidget1" );
pAnimWidget->setGeometry( QRect( 140, 90, 90, 90 ) );
pAnimWidget->setSize( 88 );

to the constructor of the ChapterSevenAnimationWidget class. And here you can also see the problem with this widget from the outset. Notice that the name passed to the constructor for the KAnimWidget is “kde” actually when running the program you can pretty much change this to the name of any KDE application and you will get the icon for that application, although it is unlikely to be animated.

The thinking behind it as far as I can tell is that all animations are just a series of icons and therefore the widget can use the KIconLoader to load the icons. This is fine when developing applications that are part of KDE but not so good when trying to develop independent applications because it only allows you to use the KDE system for loading the icons. The point being that if you create a test project in usr/share/ called chaptersevenanimation and add a icons folder and a pics folder placing your icons, named chaptersevenanimation there then the program will not find them if you run it with the name "chaptersevenanimation" replacing the "kde" as the first parameter to the program.

So unless you are actually developing for kde I'd steer clear of this widget as it wont let you pass a directory name in for the icon or icons that you wish to load but as I said if you want to run it and and change the "kde" it will load just about any KDE icon here as it gets them from opt/kde3/share/icons/hicolor ( on Suse ).

The rest of the application is just the adding of the start and stop buttons to test the animation. Note if you are playing around with it, not all the icons are animated so if you load an icon that isn't animated and hit start the icon will just flicker a bit as it is redrawn to the screen.


Icons

All this looking into how the animation widget works cannot help but bring us round to the subject of icons and understanding how they work in KDE. If you go to opt/kde3/share/icons ( on Suse ) you will see.


which is the directory structure for the options that are displayed when you go to Control Center/Appearance and Themes/Icons


The icons are then stored by size in the corresponding directories.


The icons size to be used on your system can be set through the Control Centre and it is here that the KIconloader used mentioned above is used throughout KDE to find the correct type and size of Icon for the system.

KDevelop Icons

One thing that's bugged me since I started looking into programming with KDevelop has been the icons it produces.


I've no idea what these are supposed to be and have completely failed to find an application including KDevelop that can open them, so in the tradition of programmers everywhere I thought stuff 'em and did it myself.

If you look at the image for the running application of chaptersevenanimation you will see that the icon in the top left is set to a little red circle. Whereas none of the previous applications have had the icon set this is because I implemented the code myself. To do this all you do is create an icon for you project. You can overwrite the icons generated by KDevelop, it doesn't matter though as they are still not used when you run the program.

To implement the icon open the main.cpp file and add the include file

#include <qpixmap.h>

Then add the icon code to the file, just after the main widget has been set.

else
{
    // no session.. just start up normally
    KCmdLineArgs *args = KCmdLineArgs::parsedArgs();

    /// @todo do something with the command line args here

   mainWin = new ChapterSevenAnimation();
   app.setMainWidget( mainWin );
   QPixmap icon;
   icon.load( "chaptersevenanimation.png" );
   mainWin->setIcon( icon );
   mainWin->show();

   args->clear();
            
}

Loading the icon and setting the main windows icon before you show it will allow you to set any icon you want for your application.

KDE Colours

The final little application we are going to look at for this chapter is the ChapterSevenColours which looks at using the KColorPalette widget and the KColorPatch widget. As neither of these will add the correct constructor code from the gui we must add them manually which means our gui development looks like this.


Which gives absolutely nothing away so we will have to look at the chaptersevenwidget constructor to see what is going on here.

colorPatch = new KColorPatch( this );
colorPatch->setGeometry( QRect( 0, 0, 533, 437 ) );
        
paletteTable = new KPaletteTable( this  );
paletteTable->setGeometry( QRect( 140, 130, 127, 151 ) );       
paletteTable->setPalette( "Web" );
        
        
connect( paletteTable, SIGNAL( colorSelected(const QColor&,const QString&) ), this, SLOT( paletteTable_colorSelected(const QColor&,const QString&) ) );

We create a new KColorPatch object and set the geometry to the size of the dialog. Then we create the KPaletteTable afterwards, doing it the other way means that the KColorPatch will completely cover the KPaletteTable and it is important that we are able to see all of that widget. Once we have set the geometry for the KPaletteTable we call setPalette with the string "Web" this selects the web colour options when the KPaletteTable loads.

The options available are,

Recent Colors

Custom Colors

Web

Royal

40 Colors

Named Colors

The KPaletteTable is the same widget that we looked at when we were looking at the colour file dialog in chapter six.

Implementing Our Own Connections

The final line in the constructor is

connect( paletteTable, SIGNAL( colorSelected(const QColor&,const QString&) ), this, SLOT( paletteTable_colorSelected(const QColor&,const QString&) ) );

This is the connection to call the ChapterSevenColours paletteTable_colorSelected function which is implemented as,

void ChapterSevenColoursWidget::paletteTable_colorSelected(const QColor& color, const QString& colorText )
{
        colorPatch->setColor( color );
}

This simply sets the KColorPatch widget to the colour that was selected in the KPaletteTable, however as we are unable to use the gui to set up the connection we must do it manually so once again. We call the connect function passing in the name of the widget that will be sending the signale and then state that the signal to be sent is the colorSelected signal and list the parameters before stating which widget will receive the signal which in the current case is this which refers to the ChapterSevenWidget class and then we list the slot that will receive the signal and list the parameters. In the heading we deaclare,

public slots:
    /*$PUBLIC_SLOTS$*/
        virtual void paletteTable_colorSelected(const QColor& color,const QString& colorText);

and then in the cpp file we add the function as listed above. Ending up with,


Summary

In this chapter we have taken our first look at some of the widgets that are exclusive to KDE beginning with the Display widgets and have taken a quick look at icons in KDE as well.