KCModules are special widgets that are used throughout the KDE platform to provide configuration functionallity. For example every module in System Settings is actually a KCM. You can also access all KCMs installed on your system using the command kcmshell4.
From a development perspective KCMs are a very good choice whenever it comes to providing the user the opportunity to configure an application. What makes KCMs particularly powerful is the fact that they are derived from QWidgets and can be use as such (looking exactly like a regular QWidget) by using it in a regular user interface. However, they can be embedded in special container widgets and applications (such as kcmshell4) to display special buttons which help with controlling the module. In such containers they get buttons to apply changes or to revert them or to revert to the default settings of the KCM, which is exactly what you see in System Settings.
This is archived by using Qt’s superb signal and slot system. KCMs have a given set of slots that are used by their containers to control stuff like saving or restoring the original defaults.
As part of my Google Summer of Code project I implemented some KCMs and eventually came the love them and I would very much like to share with you some of the things I found best. If you have never seen the code of a KCM I highly recommend taking a look at the KDE API documentation or at least one of my KCMs.
KCMs are Ubiquitous
As far as my opinion goes, I do think that KCMs are always a sensible choice when you are providing a configuration dialog in an application based on KDE technologies. KCMs, due to the fact that they are simply widgets that live inside a container, can and are used everywhere. You can list them in System Settings, but you do not need to, if the configuration is specific to your application you could just as well not list it in System Settings but use it in your application only. KInfoCenter also uses KCMs, so if you have information the user might be interested in you can also get it included in KInfoCenter.
In ubuntuone-kde I had a real configuration part and one where only information about quota and subscription are displayed, consequently I created KCMs for configuration purposes and one for information purpose.
KCMs as a Widget
One of the things I found very enjoyable was that KCMs are for the better part just QWidgets and they look exactly like regular QWidgts if they are used without a container. This for example allows to embed one KCM in another KCM (and forward function calls to the embedded KCM respectively). This is super useful if you have, like ubuntuone-kde, a KCM that is only displaying information…
As the Ubuntu One System Settings entry is the only real GUI it has, it merits to have the information KCM shown there too. In context of ubuntuone-kde particularly it made sense to combine general Ubuntu One settings with the information it has about the account. Easily done with KCMs. The KCM ubuntuone-general also contains the KCM ubuntuone-info, that way exactly the same code is used in KInfoCenter as in System Settings.
KCMs in One Library
One very nice thing is that you can combine multiple KCMs into one library. All you need to do is create a KPlugin factory, export it and add the invidiual plugins to it. This makes a lot of sense if you have an application with a lot of settings that ought to be split into multiple KCMs, this is for example the case with Konqueror, which has a vast amount of configurations, of which all are in KCMs.
You can do this easily by having for example a main.cpp that looks like this:
This creates a plugin factory for your KCM library and adds the KCModules MyModule and MyOtherModule with the names “fish” and “chips” (mind that those are not good names ;)). In the actual module implementations you then drop:
and in the ctor you construct the KCModule base like this:
MyModule::MyModule(QWidget *parent, const QVariantList &args) :
KCModule(KcmMyFactor::componentData(), parent, args)
now add a desktop file for it, for example for KInfoCenter:
Comment=A fishy fish
Finally link everything together as a plugin and voila – multiple KCMs in one library.
Have fun with KCModules🙂