Kode KDE Kindly, Kan You?

With a little programming experience, you'll have everything you need to build applications for the Linux desktop when you're done reading this.
The Document-View Model

We are not going start with a new project, but rather with the power of the Internet; we're going to use Kalculate. To get the code for Kalculate from the official CVS server, type the following (assuming you have write permissions, create a directory called /usr/local/src if you don't already have one):

cd /usr/local/src
cvs -d:pserver:anonymous@cvs.kalculate.sourceforge.net:
/cvsroot/kalculate login

If this command asks for a password, press enter; no password is needed.

cvs -z3 -d:pserver:anonymous@cvs.kalculate.
sourceforge.net:/cvsroot/kalculate co kalculate
Of course, if you want to build this application yourself, you wouldn't grab the source. But because I'm not going to do a line-by-line rundown here, it's probably best to get the source and then use your new knowledge to either add features or build a new application.

The design pattern used here is called the Document-View model. It starts out with three application-specific classes: KalculateApp, KalculateDoc and KalculateView. These three classes would have been created for you if you were freshly starting this project with KDevelop. For Kalculate, I did not add any additional classes other than what is provided in the template. I did this on purpose so that it would be easy to demonstrate the design pattern and to show just how far along KDevelop starts you. All I had to do to build a fully functional calculator was to modify three classes, add a couple of icons and voilà!

The basic rundown of Document-View is that the business logic goes into the document end, and the user-interface stuff goes into the view end. In theory, there could be several views of the same document. In the generic sense, a “document” is one open session of a “thing”. Naturally, this is easiest to comprehend with something like a text editor. In that scenario, the document object would represent all the behaviors and properties of a text file, whereas the view object would provide the display and user interface of the text to the screen. You'll even notice in the skeleton code that saving, printing, opening and closing routines are stubbed out for you. Clearly the text editor metaphor is the basis for this model.

However, as is the case for Kalculate, this metaphor doesn't always work. A calculator doesn't really have a file it represents; it has a certain set of functionality it represents. So although the KalculateDoc class will provide our business logic, we have no need for the open, close, save and print functionality. For now, in the Kalculate code, I commented out the stock code (that KDevelop provides) that I didn't need instead of deleting it. This way, if the need arises, we still have the stub.

What we do need for a calculator, on the business logic side of things (KalculateDoc), is to be able enter numbers, assign actions for those numbers and get the resulting number (and of course, internally it actually needs to perform the actions). On the user-interface side, we need buttons for entering the numbers and entering actions, and we need a display of the numbers. Assuming you put the cvs checkout into /usr/local/src, you'll have a /usr/local/src/kalculate directory. Type the following:

cd /usr/local/src/kalculate
kdevelop  kalculate.kdevprj &

This will open up the project. KDevelop stores its project info into a file named after the project with a .kdevprj ending. Depending on how you have your preferences set up, you should see something like Figure 3. If you don't see a project tree on the left side, make sure that View-->Tree Tools Views-->Files is selected. You will see the project file structure click into the kalculate directory (yes, this is a kalculate directory under a kalculate directory, don't clear your eyes). Here are all the source files. Of particular interest now are the kalculatedoc.cpp and kalculatedoc.h files. Double click them. These two files are the core of our calculator—the KalculateDoc class handles all of the processing. It's a virtual machine that needs someone to hook up controls to it. If you view kalculatedoc.h, you'll notice something very odd about the class declaration—there's some seemingly incorrect syntax. This brings us to the world of slots and signals.

Figure 3. KDevelop Project File

Slots and Signals

In event-driven applications, such as desktop applications, a subsystem needs to be built that allows components to be notified when an event occurs. An event could be some type of user interaction (moving the mouse pointer, pressing the mouse button, pressing a key, etc.). Events also may be other software components announcing some condition (e.g., the time, a full filesystem, etc.). A popular event in GUI applications, and especially Kalculate, is that a button widget has been pressed. In KDE land, events are called signals, and the things that handle the events are called slots. As the developer, you can create signals and slots, and you can control which slots are connected to which signals. You can also connect your slots to stock signals (and vice versa) or connect stock signals to stock slots. By stock I mean using a KDE or Qt library class that already has slots and/or signals defined.

KDE (and thus Qt) gets away with the incorrect syntax because it uses the standard C++ preprocessor #defines that replace signals: with protected: and slots and emit with nothing. The extra syntax is needed by moc (which is run before the preprocessor). The Meta Object Compiler (moc) is a program that comes with the Qt library and is run on your QObject header files in order to create extra methods for your classes that make them usable as a QObject subclass. All objects that use slots and signals must be a subclass of QObject, and the class definition must have the Q_OBJECT macro called (as you can see in the kalculatedoc.h file). The QObject superclass has a connect method, and that is the method you use to connect your slots and signals.

To create signals, declare them under signals: in your class declaration. For signals, you don't really have to create a subsequent method. All you have to do is call emit on the signal name, and any slot that is connected to it will be called; moc actually creates the signal method for you.

Slots, on the other hand, do have to be created. You declare your slots under public slots, or protected slots, and then define them as normal methods in your .cpp file. You can then connect them anytime you want. Like this:

connect(this, SIGNAL( mySignal() ),
        this, SLOT( mySlot() ) );

Assuming you have defined a signal called mySignal() and a slot called mySlot() within the same class, the above call to connect would bind them together so that any time emit mySignal() is called, mySlot() will get called. If you wanted to connect your slot to some other signal in some other object, then your first argument would be the instance of the object, and your second argument would be the SIGNAL() macro with the name of the signal inside the parentheses. It's that easy. All the hard stuff (including running moc on your headers) is done by KDevelop.

So (back to our calculator) the KalculateDoc class is a series of slots. Each slot represents an action one would take on a calculating machine. The header file declares all the slots as shown in Listing 1. Again, the only thing that makes these methods special is that they are under a “public slots:” label, and thus moc will create some metadata about them. As slots, you still need to define the methods as normal (look at kalculatedoc.cpp to see my definitions of these slots). Signals, on the other hand, you do not define; moc does that for you.

Listing 1. Slots

So now all we need is a GUI that uses this class. Enter KalculateView (I hope you are actually opening up the source code and checking it out). The kalculateview.h file defines our class that provides the GUI. Under “protected” you'll see that several layout managers, an LCD display and several buttons are declared. I did add one file to KDevelop's stock template code; it's called kalculatesizes.h, and here is what is in it:

#ifndef KALCULATE_SIZES_H
#define KALCULATE_SIZES_H
#define BUTTON_WIDTH 35
#define BUTTON_HEIGHT 35
#define LAYOUT_SPACING 4
#define MAX_WIDTH (BUTTON_WIDTH * 5)
        + ((LAYOUT_SPACING *2) * 4)
#define MAX_HEIGHT (BUTTON_HEIGHT * 5)
        + ((LAYOUT_SPACING *2) * 4)
#endif // SIZES_H

Basically, it sets up the size of our calculator. I decided to go with a calculator that isn't resizable, but I wanted to make it easy to change the button sizes. So I define the sizes in this file. All one needs to do is edit this file and recompile to get a calculator with different-sized buttons (perhaps future versions could allow for this on the fly, but I'm hesitant for some reason).

In KalculateView, constructor (in kalculateview.cpp) is where this application comes to life. The call to setMaximumSize() is what makes this not resizable. The size policy helps out too, but is just a suggestion. I'll take a moment here and explain layout managers. Basically, every GUI widget has methods to set its geometry (height, width, relative position, etc.). When an application is first set up, and when it's subsequently resized, it wouldn't be very fun if you had to write code that resized or repositioned it. And on the initial setup, without a layout manager, all the buttons in this application would have to be positioned with hard-coded x/y coordinates. That could take hours of time when you wanted to change the size of the calculator. So, instead of hard-coding geometry attributes, we register our widgets with layout managers that follow certain rules, for example, the QVBoxLayout, which adds widgets in a vertical column. Every time you put a widget in with the addWidget() method like this:

outerLayout->addWidget(output,1);

it adds the widget just below the previous widget. A QHBoxLayout would add the widget just to the right of the previous one. The second argument is what is called the stretch factor. Basically, the stretch factor decides how much space this widget is going to take in relation to the other widgets added to this layout manager. So if they are all 1, then they will all be the same size (unless factors like setMaximumSize override it). It takes the sum of all the stretch factors and applies a ratio. So if you had two widgets, the first with the stretch factor of 1 and the second with a stretch factor of 2, then the second would be twice as big as the first.

The really cool thing (as exemplified in KalculateView) is that you can add layout managers to layout managers. This allows you to create very complex layouts. Go ahead and play around with the Kalculate code; see what you can create.

So, to run this application, do the following. Select Autoconf and Automake from the Build menu. Then select Configure from the Build menu. When this asks for arguments, type --prefix=[your base kde dir]. This will allow you to install the application, which is needed if you want the application's icon to show up. On my machine, which is Mandrake, the base directory for KDE is /usr. Your distro may differ. Then, select Execute from the Build menu, and it will compile and run. You should see something like Figure 4. But the icon in the upper left-hand corner may be missing until you install it. To install, as root type:

cd /usr/local/src/kalculate
make install
<center>

Figure 4. Kalculate

I hope I have pointed you in the right direction. I have barely scratched the surface of all the things you can do with KDE, but I have shown you how quickly KDevelop allows you to get started. It handles almost all the back-end work for you and gives you an application that compiles on the command line without the presence of KDevelop (this is good for distributing your code). Feel free to e-mail me if you have any questions, and I encourage you to join the Kalculate team and add some features.

email: jmott@users.sourcforge.net

Jason Mott (jmott@users.sourceforge.net) is an independent software consultant currently on assignment at ElementK (www.elementk.com) in Rochester, New York, helping to build their on-line training site. He is also a part-time Linux consultant, and when he has spare time, he builds Linux desktop applications.

______________________

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Re: Kode KDE Kindly, Kan You?

synthetoonz's picture

I would have liked to see a more entry level explanation of everything. Why are things (functions/objects/classes) arranged the way they are? A line by line breakdown of the code would be excellent.

I'm not exactly entry level. I was writing Motif and X11 code 12 years ago in the Air Force. But, things must have changed a lot in the years since I've worked on *ix guis, because much of the code I see in various KDE/GTk applications seems like nonsense.

I've been sifting through all the "tutorials" I can find on the web about beginning KDE development and have not had much luck getting most of them to even compile (Suse 8.1 pro/KDE 3). (BTW, this calculator app is one of the few that actually do compile on my system.)

I was following one step-by-step tutorial I found online and it began to fall apart after the work they outlined in QT designer was finished. The source code lines they said had to be manually edited didn't exactly look the same as their example, and once edited the project wouldn't build. Grrr. There is some unknown voodoo going on.

I have done work in MFC for Windows (Bleh) and at least there in Visual studio you can get a brainless GUI dialog/window to appear without editing any code. I think part of the problem with the KDE/KDevelop/QT design tools is that things are too loosely linked. They function almost as if they are totally unaware of each other. Having to edit/change certain generic class names used as boilerplate or placeholders in a source file should be done by the tools, not the programmer -- isn't that's what the tools are for.

I think a series of articles explaining KDE/GT development in a step-by-step, line-by-line exposition would a right nifty idea in LinuxJournal. (Perhaps a regular column dedicated to beginner level development.)

Re: Kode KDE Kindly, Kan You?

synthetoonz's picture

Oops.

:%s/GT/Qt/g

heh heh.

Re: Kode KDE Kindly, Kan You?

stampa's picture

Jason, many thanks for your easy to understand article. I am new to Linux and it has inspired me to try to develop a simple Linux app. Previously I was a little confused by KDE/Qt etc but I now want to give it a go. If successful I may be intersested in doing something useful for Sourceforge one day..

I'm disappointed by some of the negative comments people seem to enjoy writing here - I think they should probably get out more and communicate other than by computer once in a while? Thanks again.

Re: Kode KDE Kindly, Kan You?

jmott's picture

Thanks for your kind words. I wish you luck in your KDE/QT adventures.

Don't worry about those that make negative comments. They are clearly not very intelligent, and have some serious emotional issues to work out.

Re: Kode KDE Kindly, Kan You?

Anonymous's picture

Good article. Simple is exactly what new Qt developers need to get started. I am coming from an MFC/Windows environment and this is the kind of straightforward article i need to get aquainted with cvs, Qt, and the general development process on Linux.

Muchas Grassy-ass

Re: Kode KDE Kindly, Kan You?

jmott's picture

Glad you liked it!

Re: Kode KDE Kindly, Kan You? Trouble with KDE3 on SuSE 8

Anonymous's picture

I can't get this to work at all on SuSE 8. ;o)

I guess kde 2.2.2 must have some Q?Something that KDE 3 don't got.

Re: Kode KDE Kindly, Kan You? Trouble with KDE3 on SuSE 8

jmott's picture

Kalculate requires KDE 2.2.2, and Suse 8.0 comes with KDE 3.0. KDE 3 changes enough that it isn't compatable with KDE 2.2.2 apps.

Sorry. When the article gets old enough, I'll port Kalculate to KDE 3.0. But since the article states it's a KDE 2.2.2 app I need to wait.

Re: Kode KDE Kindly, Kan You? Trouble with KDE3 on SuSE 8

Anonymous's picture

Rodger that. I knew I wasn't crazy. So I picked up a nice little book on TCL/TK for now. That ought to keep me busy ;o)

Thanks for the response.

Re: Kode KDE Kindly, Kan You? Trouble with KDE3 on SuSE 8

Anonymous's picture

You need to be superuser. So type "su"

and follow with root password.

A great framework article

Romulus007's picture

Jason,

Great job!! Some people are simply un-appreciative of the time (FREE) that others put in to make this community what it is today.

I have not started any Linux development yet, but I will soon. Also, I'm a big Delphi (Object Pascal) fan, but this KDevelop stuff is truly impressive.

Finally, I have to give a big thanks to the KDE folks! They just seem to have an aura of "extreme kwality" about them, whether it's their apps (like KOffice) or their desktop environment.

It's sure good to know that the open source world has them along with the other members of GNOME, Apache, Linux, JBoss, XFree86, MySQL, PostGre, NetBeans, the BSDs (Net, Free, Open), GNU, Eclispe et al (I'm sure I've forgotten other notables!).

History, one day, will rightfully give all of the above mentioned organizations a big THANK YOU for allowing the masses to regain their diginity from proprietary apps or companies that only care about satisfying sahreholders to the detriment of society.

In other words, I am eternally gratefull for all of the wonderful contributions made by everyone in the open source community. It, truly, has inspired me in numerous ways!

L8tr dudes!!

Re: A great framework article

jmott's picture

Thank you so much for your kind words. It's nice to get a complement in an environment where people are all too quick to throw insults.

--Jason

Re: Kode KDE Kindly, Kan You?

Anonymous's picture

using a doc/view for this application is a huge design mistake! That might have "undefined" consequences on newbie developer who are reading this article.

Very poor practive indeed from an article which aims at teaching.

Re: Kode KDE Kindly, Kan You?

jmott's picture

I think it's a very good design, and so do the developers of KDevelop, as it's the default template. I also believe in teaching the real world. I don't insult learners by dumbing down material.

However, I have an open mind. I'd love to hear more details about your opinion.

--Jason

Re: Kode KDE Kindly, Kan You?

Anonymous's picture

Perhaps you're not familiar with KDevelop, but the KDE project template creates app, doc and view source files. It wouldn't make much sense to tell a beginner to ignore the project template, and hand code something.

If the project only took two hours to create, I fail to see any huge design mistake.

-- Richard Dale

Re: Kode KDE Kindly, Kan You?

Anonymous's picture

please correct the first cvs-statement (cvs -d:pserver:anonymouscvs.kalculate.sourceforge.net) into

(cvs -d:pserver:anonymous@cvs.kalculate.sourceforge.net)

the @ is missing.

-gunnar

Re: Kode KDE Kindly, Kan You?

Anonymous's picture

Help
italica

Re: Missing @

scott's picture

Thanks.

Re: Kode KDE Kindly, Kan You?

Anonymous's picture

Interesting to see an article posted in the future coming back to haunt us:
"Issue 98: Kode KDE Kindly, Kan You?
Posted on Saturday, June 01, 2002 by Jason Mott"

Re: Kode KDE Kindly, Kan You?

Anonymous's picture

No surprise. When I set timezone in my KDE to UTC, I kan see UTC. If I set timezone for Prague (today UTC+2), I will see just the opposite time: UTC-2, i.e. at 8:00 my KDE panel clock applet insists it is only 4:00.

So if the author acutally wrote the article on May 1 and posted May 15, KDE consistently with its clock logic translated the real creation date (today-15) to KDE date (today+15).

Actually it does not work precisely that, but there might a some time shift involved, too.

73,

OK1FOU

Re: Kode KDE Kindly, Kan You?

Anonymous's picture

Window managers are just clients. They can (and are) written using toolkits. So, the diagram is a bit skewed, window managers should be placed on the client side of TCP/IP, above Xlib certainly, most appropriately at the level of GNOME or KDE. The Motif window manager

In olden days (I've been working with X for about 12 years now), X terminals often had embedded window managers. In one implementation I worked on (an X terminal for NEC in Japan), we also hosted the client libraries (Motif, etc.) on the X server, and the window manager (mwm) was calling Motif directly. In other cases, custom window managers were written that made calls directly into X server routines, bypassing Xlib entirely. In both these cases, placing the window on the side of the X server would be correct. But these are exceptions to the general rule; window managers are clients.

Re: Kode KDE Kindly, Kan You?

jmott's picture

Window Managers were really out of scope for this article, so I tucked it down at the bottom. Sorry for any confusion that may have caused, but applications are really the focus here, not Window Managers.

Thanks for the feedback.

--Jason

Re: Kode KDE Kindly, Kan You?

Anonymous's picture

It's a common misconception to think of KDE as a window manager. Although KDE comes with a window manager, it's certainly not limited to that.

Basically KDE is three things:

* An application development framework. (High Level API)

* The actual Desktop (window manager, panel, desktop with icons, control center, file manager)

* A large number of consistent and easy to use applications.

This article focuses on the first aspect and as such has little to do with window managers.

Cheers,

Waldo Bastian

bastian@kde.org

Re: Kode KDE Kindly, Kan You?

Anonymous's picture

It must be late because it is only now that I notice the "Window Manager" in Figure 1.

Yes, the poster is absolutely right. kwin, the KDE window manager, sits on top of the KDE API on the client side.

Cheers,

Waldo Bastian

bastian@kde.org

Re: Kode KDE Kindly, Kan You?

Anonymous's picture

I think he really meant www.kdevelop.org, not .com...

I don't "kare" enough to waste my time on KDE "krap", but you've got to wonder if the rest of the article is so full with little errors like this.

Re: Kode KDE Kindly, Kan You?

Anonymous's picture

Why is KDE programming "krap"?

Get a life and don't slag off people who put a lot

of effort into articles such as this.

Nick

Re: kdevelop.org

scott's picture

Thanks, I'll have that fixed.

Re: Kode KDE Kindly, Kan You?

Anonymous's picture

I just dont see why this dummy chooses to encourage the dumb naming tendencies that KDE and GNOME both have. Kuz I KThink KThe KNaming KIs KStupid. GDoesn't GMatter GWhich GDesktop. Retards. Get some focking creativity.

Re: Kode KDE Kindly, Kan You?

jmott's picture

Dummy? I wrote an intelligent, well written article that the The Linux Journal felt fit to not only print in its magazine, but to pay me for. I'm not sure I'm the dummy here. However, if you must know why I encourage the use of the K naming convention I will tell you. It's because there is so much choice on the Linux desktop. The naming convention instantly tells you what the application is written for. So, if you don't like KDE, now you know what applications to avoid.

If you really want to critique articles, I recommend you come up with some more intelligent reviews rather then throwing around 5 year old level insults at someone whom you've never meet, and indeed has feelings.

You might want to also read the articles first.

Re: Kode KDE Kindly, Kan You?

Anonymous's picture

He's a Koward, get it!

Re: Kode KDE Kindly, Kan You?

Terry's picture

Well, I thought it was an excellent article.

Considering the schmoe who wants to toss around names dosn't have the guts to sign his own flame...

***** him!

As far as the kNaming Konvention... I'll agree with both sides. It's kinda dumb on the surface, but it is usefull. Of course your free to gname gyour gKDE gapplications gany gway gyou gwant. ;>)

Peace,

Terry.

Re: Kode KDE Kindly, Kan You?

Anonymous's picture

Yes, it looks stupid, but is quite practical.

Re: Kode KDE Kindly, Kan You?

Anonymous's picture

I agree. When I read the Freshmeat updates, I can easily jump over everything that starts with a K. :)

But naming is something there where always around: who remember all that programs "for Windows"? Or PM-something or Something/2? Or even Xsomething? Althought some of them are really stupid, it is simpler to recognize what operating system or toolkit the program uses.

Re: Kode KDE Kindly, Kan You?

Anonymous's picture

motif has been open for about 2yrs...

www.openmotif.org

Re: Kode KDE Kindly, Kan You?

Anonymous's picture

But look at the license. It is only free for open source OS. So thast prohibits development on say Linux and then running the Application on Solaris, AIX, etc.

Re: Kode KDE Kindly, Kan You?

Anonymous's picture

> motif has been open for about 2yrs...

It seems to me it has also been irrelevent for at least that long. It has certainly been ugly for a very long time. At any rate since KDE and the follow up of GNOME Motif wasn't exactly giving up the farm by finally opening. If they had done it years ago they might be more than a footnote in history.

Webinar
One Click, Universal Protection: Implementing Centralized Security Policies on Linux Systems

As Linux continues to play an ever increasing role in corporate data centers and institutions, ensuring the integrity and protection of these systems must be a priority. With 60% of the world's websites and an increasing share of organization's mission-critical workloads running on Linux, failing to stop malware and other advanced threats on Linux can increasingly impact an organization's reputation and bottom line.

Learn More

Sponsored by Bit9

Webinar
Linux Backup and Recovery Webinar

Most companies incorporate backup procedures for critical data, which can be restored quickly if a loss occurs. However, fewer companies are prepared for catastrophic system failures, in which they lose all data, the entire operating system, applications, settings, patches and more, reducing their system(s) to “bare metal.” After all, before data can be restored to a system, there must be a system to restore it to.

In this one hour webinar, learn how to enhance your existing backup strategies for better disaster recovery preparedness using Storix System Backup Administrator (SBAdmin), a highly flexible bare-metal recovery solution for UNIX and Linux systems.

Learn More

Sponsored by Storix