* [http://websvn.kde.org/trunk/KDE/kdeutils/superkaramba/examples/ Examples] Some examples SuperKaramba ships with. See also the [http://www.kde-look.org/index.php?xcontentmode=38 Themes] and [http://www.biodesign.com.ar/blog/?cat=2 More Themes].

* [http://websvn.kde.org/trunk/KDE/kdeutils/superkaramba/examples/ Examples] Some examples SuperKaramba ships with. See also the [http://www.kde-look.org/index.php?xcontentmode=38 Themes] and [http://www.biodesign.com.ar/blog/?cat=2 More Themes].

SuperKaramba does differ between 3 kind of elements. Commands define something that should be done (actions), meters are used to display something (GUI widgets) while sensors are to get something (data delivery).

+

+

* A list of [http://netdragon.sourceforge.net/sgeneral.html General Commands] that you can put in your theme file. This includes tags that define the widget shape, set default fonts, and create click-areas that launch programs.

+

* A list of [http://netdragon.sourceforge.net/smeters.html Meters] that you can put in your theme file. This includes meters display the values of sensors. Meters can auto-update.

+

* A list of [http://netdragon.sourceforge.net/ssensors.html Sensors] that you can put in your theme file. Sensors allow you to display system properties automatically. There are sensors to display the status of everything from memory use to the results of shell scripts. See here also the [[#Plasma::DataEngine_as_SuperKaramba_Sensor|Plasma::DataEngine as SuperKaramba Sensor]] chapter.

==Basic Tutorial for Theme Creators==

==Basic Tutorial for Theme Creators==

Line 23:

Line 31:

The theme files, those files with the fileextension *.theme, are text files that contain layout information and information about the values that will be shown.

The theme files, those files with the fileextension *.theme, are text files that contain layout information and information about the values that will be shown.

−

====Commands, Meters and Sensors====

+

====Theme File Samples====

−

+

−

* A list of [http://netdragon.sourceforge.net/sgeneral.html General Commands] that you can put in your theme file. This includes tags that define the widget shape, set default fonts, and create click-areas that launch programs.

+

−

* A list of [http://netdragon.sourceforge.net/smeters.html Meters] that you can put in your theme file. This includes meters display the values of sensors. Meters can auto-update.

+

−

* A list of [http://netdragon.sourceforge.net/ssensors.html Sensors] that you can put in your theme file. Sensors allow you to display system properties automatically. There are sensors to display the status of everything from memory use to the results of shell scripts

+

−

+

−

====Samples====

+

The simplest form of Karamba is to load a file containing the word karamba. This will give you a empty transparent window with the size 300x300. A better idea is to enter something like this in a file:

The simplest form of Karamba is to load a file containing the word karamba. This will give you a empty transparent window with the size 300x300. A better idea is to enter something like this in a file:

# Make a theme file like described at the "Creating the Theme File" chapter above.

# Make a theme file like described at the "Creating the Theme File" chapter above.

−

# Download [http://websvn.kde.org/trunk/KDE/kdeutils/superkaramba/examples/template.py template.py] or the [http://websvn.kde.org/trunk/KDE/kdeutils/superkaramba/examples/template.rb template.rb] or the [http://websvn.kde.org/trunk/KDE/kdeutils/superkaramba/examples/template.js template.js] script file, depending on what scripting language you like to use, and rename this file to match your theme file.

+

# Download the [http://websvn.kde.org/trunk/KDE/kdeutils/superkaramba/examples/template.py template.py] or the [http://websvn.kde.org/trunk/KDE/kdeutils/superkaramba/examples/template.rb template.rb] or the [http://websvn.kde.org/trunk/KDE/kdeutils/superkaramba/examples/template.js template.js] script file, depending on what scripting language you like to use, and rename this file to match your theme file.

# Fill in all the callbacks in the script file that you want to handle. The template files just contain all callbacks, but you can safly remove those you don't need or just leave them in.

# Fill in all the callbacks in the script file that you want to handle. The template files just contain all callbacks, but you can safly remove those you don't need or just leave them in.

# Use the [[Projects/SuperKaramba/API|API Reference]] to know what commands to use to fill in the callbacks.

# Use the [[Projects/SuperKaramba/API|API Reference]] to know what commands to use to fill in the callbacks.

Line 91:

Line 97:

First, you need the [http://websvn.kde.org/trunk/KDE/kdeutils/superkaramba/examples/template.py template.py] or the [http://websvn.kde.org/trunk/KDE/kdeutils/superkaramba/examples/template.rb template.rb] or the [http://websvn.kde.org/trunk/KDE/kdeutils/superkaramba/examples/template.js template.js] template script file, depending on what scripting language you like to use. Download this file to where your theme file is. Now rename those just downloaded template file from template.py to mytheme.py or from template.rb to mytheme.rb where mytheme is the name of your theme. For example, if you wrote a coolbar.theme and like to use use Python, renamed the just downloaded template.py to coolbar.py and put it in the same directory as coolbar.theme.

First, you need the [http://websvn.kde.org/trunk/KDE/kdeutils/superkaramba/examples/template.py template.py] or the [http://websvn.kde.org/trunk/KDE/kdeutils/superkaramba/examples/template.rb template.rb] or the [http://websvn.kde.org/trunk/KDE/kdeutils/superkaramba/examples/template.js template.js] template script file, depending on what scripting language you like to use. Download this file to where your theme file is. Now rename those just downloaded template file from template.py to mytheme.py or from template.rb to mytheme.rb where mytheme is the name of your theme. For example, if you wrote a coolbar.theme and like to use use Python, renamed the just downloaded template.py to coolbar.py and put it in the same directory as coolbar.theme.

−

Now, lets open up your coolbar.py (or coolbar.rb or whatever you named it to) scripting file. Look for the event callback that reacts to mouse movement. In the case you choosed Python as your prefered scripting language, it may look like this:

+

Now, lets open up your coolbar.py (or coolbar.rb or whatever you named it to) scripting file. Look for the event callback that reacts to mouse movement. If you chose Python as your prefered scripting language, it may look like this:

−

<code python>

+

<syntaxhighlight lang="python">

#This gets called everytime our widget is clicked.

#This gets called everytime our widget is clicked.

#Notes

#Notes

Line 110:

Line 116:

#want to run complex piece of code everytime the mouse moves.

#want to run complex piece of code everytime the mouse moves.

pass

pass

−

</code>

+

</syntaxhighlight>

Notice how the template gives your instructions on what data each callback gives you. In this case, you can see that you will know the x and y co-ordinates of the mouse, the button being held down (if any), and a reference to your widget.

Notice how the template gives your instructions on what data each callback gives you. In this case, you can see that you will know the x and y co-ordinates of the mouse, the button being held down (if any), and a reference to your widget.

Line 122:

Line 128:

Here is how the callback might look after you add some code to it:

Here is how the callback might look after you add some code to it:

−

<code python>

+

<syntaxhighlight lang="python">

def widgetMouseMoved(widget, x, y, button):

def widgetMouseMoved(widget, x, y, button):

myText = karamba.getThemeText(widget, "mouseText")

myText = karamba.getThemeText(widget, "mouseText")

karamba.changeText(widget, myText, "mouse at %s:%s" % (x,y))

karamba.changeText(widget, myText, "mouse at %s:%s" % (x,y))

−

</code>

+

</syntaxhighlight>

−

This Python scripting code simply changes the text called "mouseText" (which we defiend in our theme file) to tell us the current position of the mouse.

+

This Python scripting code simply changes the text called "mouseText" (which we defined in our theme file) to tell us the current position of the mouse.

How did I know what parameters karamba.changeText() and karamba.getThemeText() used? How did I even know those functions existed in the first place? Well, thats what the [[Projects/SuperKaramba/API|API]] tells you. The API and the template.py or template.rb script file basically contain everything you could ever need to know to write your own theme.

How did I know what parameters karamba.changeText() and karamba.getThemeText() used? How did I even know those functions existed in the first place? Well, thats what the [[Projects/SuperKaramba/API|API]] tells you. The API and the template.py or template.rb script file basically contain everything you could ever need to know to write your own theme.

−

====Testing!====

+

===Testing!===

To test your new Python or Ruby scripting code, just open your theme file in SuperKaramba.

To test your new Python or Ruby scripting code, just open your theme file in SuperKaramba.

Line 138:

Line 144:

You DO NOT need to compile your scripting code. SuperKaramba will do that automatically and tell you about any errors. In fact, you can't run your .py or .rb file directly in regular python because it doesn't know anything about the karamba.* functions. Those functions only exist inside of SuperKaramba's Python and Ruby interpreters. But you are for sure able to just use SuperKaramba as your interpreter direct from within the commandline. Just start SuperKaramba with something like:

You DO NOT need to compile your scripting code. SuperKaramba will do that automatically and tell you about any errors. In fact, you can't run your .py or .rb file directly in regular python because it doesn't know anything about the karamba.* functions. Those functions only exist inside of SuperKaramba's Python and Ruby interpreters. But you are for sure able to just use SuperKaramba as your interpreter direct from within the commandline. Just start SuperKaramba with something like:

−

<code bash>

+

<syntaxhighlight lang="bash">

superkaramba ./coolbar.theme

superkaramba ./coolbar.theme

−

</code>

+

</syntaxhighlight>

To ease the development, SuperKaramba will automatically reload your theme when you save your changes to the theme file or the script file. This allows you to see your modifications immediately without reloading the theme manually.

To ease the development, SuperKaramba will automatically reload your theme when you save your changes to the theme file or the script file. This allows you to see your modifications immediately without reloading the theme manually.

Line 150:

Line 156:

===SuperKaramba on KDE4===

===SuperKaramba on KDE4===

−

While we where able to see a lot of rumours and speculations regarding SuperKaramba and it's role on KDE4, it's planned to continue to support SuperKaramba and it's unique feature-set, the bunches of themes that do already exist and those that will be written. We will stay backward-compatible and rocking stable, improve the feature-set as needed and wish you fun with the result: the next generation of SuperKaramba :)

+

While we were able to see a lot of rumours and speculations regarding SuperKaramba and it's role on KDE4, it's planned to continue to support SuperKaramba and it's unique feature-set, the bunches of themes that do already exist and those that will be written. We will stay backward-compatible and rocking stable, improve the feature-set as needed and wish you fun with the result: the next generation of SuperKaramba :)

+

+

===SuperKaramba and Plasma===

+

+

SuperKaramba runs as standalonea-application - just run the program "superkaramba" - as well as [[Projects/Plasma|Plasma]] Applet embedded into the Plasma Workspace. Also SuperKaramba provides full and transparent access to the Plasma::DataEngine's with it's sensor functionality.

+

+

See also the [[Development/Tutorials/SuperKaramba#Plasma|Plasma script samples]] section.

===Scripting Interpreter Backends===

===Scripting Interpreter Backends===

Line 160:

Line 172:

As described at the Python Enhancement Proposal [http://www.python.org/peps/pep-0263.html Defining Python Source Code Encodings] it is recommed to start a python script file with following both lines:

As described at the Python Enhancement Proposal [http://www.python.org/peps/pep-0263.html Defining Python Source Code Encodings] it is recommed to start a python script file with following both lines:

−

<code python>

+

<syntaxhighlight lang="python">

−

#!/usr/bin/env superkaramba-bin

+

#!/usr/bin/env superkaramba

# coding: utf-8

# coding: utf-8

−

</code>

+

</syntaxhighlight>

The first line is the shebang that causes Unix-like operating systems to execute the script file using the SuperKaramba interpreter. You are then able to start the karamba script with;

The first line is the shebang that causes Unix-like operating systems to execute the script file using the SuperKaramba interpreter. You are then able to start the karamba script with;

−

<code>

+

<syntaxhighlight lang="text">

chmod 755 myKaramba.py

chmod 755 myKaramba.py

./myKaramba.py

./myKaramba.py

−

</code>

+

</syntaxhighlight>

−

The second line defines that the script file is encoded with utf-8 or whatever the script fiel is actualy encoded in. This seems to be needed at least with Python >=2.5.

+

The second line defines that the script file is encoded with utf-8 or whatever the script file is actualy encoded in. This seems to be needed at least with Python >=2.5.

==Script Samples==

==Script Samples==

Line 180:

Line 192:

theme written in Ruby. The theme just displays the current time in a RichText widget.

theme written in Ruby. The theme just displays the current time in a RichText widget.

−

<code ruby>

+

<syntaxhighlight lang="ruby">

require 'karamba'

require 'karamba'

Line 195:

Line 207:

Karamba.redrawWidget(widget)

Karamba.redrawWidget(widget)

end

end

−

</code>

+

</syntaxhighlight>

The initWidget method will be called once if the widget got initialized. Here we setup the RichText widget where we display the current time in. The widgetUpdated will be called each second once (the interval is defined in the [http://websvn.kde.org/trunk/KDE/kdeutils/superkaramba/examples/rubyclock/clock.theme?view=markup clock.theme] themefile) and just updates the text display in the RichText widget with the new time.

The initWidget method will be called once if the widget got initialized. Here we setup the RichText widget where we display the current time in. The widgetUpdated will be called each second once (the interval is defined in the [http://websvn.kde.org/trunk/KDE/kdeutils/superkaramba/examples/rubyclock/clock.theme?view=markup clock.theme] themefile) and just updates the text display in the RichText widget with the new time.

Line 201:

Line 213:

Let's take a look at another theme. The [http://websvn.kde.org/trunk/KDE/kdeutils/superkaramba/examples/text/text.py?view=markup text.py] theme written in Python just displays some text widgets. We take this as example to create our own script, that does the same as the [http://websvn.kde.org/trunk/KDE/kdeutils/superkaramba/examples/rubyclock/clock.rb?view=markup clock.rb] above, that is to display the current time within a text widget.

Let's take a look at another theme. The [http://websvn.kde.org/trunk/KDE/kdeutils/superkaramba/examples/text/text.py?view=markup text.py] theme written in Python just displays some text widgets. We take this as example to create our own script, that does the same as the [http://websvn.kde.org/trunk/KDE/kdeutils/superkaramba/examples/rubyclock/clock.rb?view=markup clock.rb] above, that is to display the current time within a text widget.

−

<code python>

+

<syntaxhighlight lang="python">

import karamba, time

import karamba, time

Line 219:

Line 231:

karamba.changeText(widget, text, getTime())

karamba.changeText(widget, text, getTime())

karamba.redrawWidget(widget)

karamba.redrawWidget(widget)

−

</code>

+

</syntaxhighlight>

In the initWidget method we create our text widget that is updated once per second (or per interval as defined in the matching theme file) at the widgetUpdated method to display the new current time.

In the initWidget method we create our text widget that is updated once per second (or per interval as defined in the matching theme file) at the widgetUpdated method to display the new current time.

Line 226:

Line 238:

There we have the currentTime() function that returns the current time as string. That function is used within the initWidget() and the widgetUpdated() functions to display the current time within a textwidget.

There we have the currentTime() function that returns the current time as string. That function is used within the initWidget() and the widgetUpdated() functions to display the current time within a textwidget.

−

<code javascript>

+

<syntaxhighlight lang="javascript">

var text = 0;

var text = 0;

Line 248:

Line 260:

karamba.redrawWidget(widget)

karamba.redrawWidget(widget)

}

}

−

</code>

+

</syntaxhighlight>

See also...

See also...

Line 260:

Line 272:

The following sample Python script demonstrates how to display a messagebox.

The following sample Python script demonstrates how to display a messagebox.

−

<code python>

+

<syntaxhighlight lang="python">

import karamba, Kross

import karamba, Kross

Line 269:

Line 281:

elif button == 2: #middle

elif button == 2: #middle

forms.showMessageBox("Error","Caption","Message")

forms.showMessageBox("Error","Caption","Message")

−

</code>

+

</syntaxhighlight>

While the next sample Python script displays a dialog with an embedded "Open File" widget.

While the next sample Python script displays a dialog with an embedded "Open File" widget.

−

<code python>

+

<syntaxhighlight lang="python">

import karamba, Kross

import karamba, Kross

Line 288:

Line 300:

if result:

if result:

print openwidget.selectedFile()

print openwidget.selectedFile()

−

</code>

+

</syntaxhighlight>

For sure you are also able to use those handy UI-files the QtDesigner produces like demonstrated on the sample below.

For sure you are also able to use those handy UI-files the QtDesigner produces like demonstrated on the sample below.

−

<code python>

+

<syntaxhighlight lang="python">

import karamba, os, Kross

import karamba, os, Kross

Line 306:

Line 318:

# lineedit-widget that has the name MyLineEdit

# lineedit-widget that has the name MyLineEdit

print infoswidget["MyLineEdit"].text

print infoswidget["MyLineEdit"].text

−

</code>

+

</syntaxhighlight>

−

===Control KSpread===

+

===Embed KHTML Webbrowser===

+

+

Starting with Qt 4.4 and KDE 4.1 SuperKaramba is able to embed any kind of QWidgets into the canvas that is used to display something. That means, you are able to add a QLabel, a QPushButton or any other widget just direct into your Karambas.

+

+

The following python sample code, which is also available as [http://websvn.kde.org/trunk/KDE/kdeutils/superkaramba/examples/WebBrowser/webbrowser.py?view=markup webbrowser.py], demonstrates this by embedding a full webbrowser into your Karamba by using the [[Projects/SuperKaramba/API#CanvasWidget|CanvasWidget]] functionality.

+

+

<syntaxhighlight lang="python">

+

#!/usr/bin/env superkaramba

+

# coding: utf-8

+

+

import karamba, Kross

+

khtml_part = None

+

+

def initWidget(widget):

+

# the Kross forms module does provide methods to create

+

# widgets for us. You are for example able to load a UI

+

# file, create layouts or just any other supported widget.

+

forms = Kross.module("forms")

+

frame = forms.createWidget("QWidget")

+

forms.createLayout(frame, "QHBoxLayout")

+

# here we load the KHTML KPart that is our full powered

+

# webbrowser widget.

+

khtml_part = forms.loadPart(frame, "libkhtmlpart")

+

khtml_part.javaScriptEnabled = True

+

khtml_part.javaEnabled = False

+

khtml_part.pluginsEnabled = False

+

# now we add the frame to our widget and will earn a

+

# proxywidget for it.

+

proxywidget = karamba.createCanvasWidget(widget, frame)

+

# the following lines demonstrate, how to control the

+

# webbrowser using the JavaScript language. The KHTML

+

# KPart does provide different signals we are able to

+

# connect our own functions too. Just see here the

+

# kdelibs/khtml/khtmlpart.h file.

+

def selectionChanged():

+

print khtml_part.executeScript("window.scrollBy(0,50);");

+

khtml_part.connect("selectionChanged()", selectionChanged)

+

# and finally we like to load an url and display something.

+

khtml_part.openUrl("http://www.kde.org")

+

+

def widgetClosed(widget):

+

# if the job is done, we may like to free our KPart again.

+

if khtml_part:

+

khtml_part.delayedDestruct()

+

</syntaxhighlight>

+

+

===KSpread===

The following sample uses KSpread to read a OpenDocument spreadsheet file and to display it within a table.

The following sample uses KSpread to read a OpenDocument spreadsheet file and to display it within a table.

Line 316:

Line 374:

While the sample is written in Python, the other supported backends like Ruby are able to access the whole same rich API.

While the sample is written in Python, the other supported backends like Ruby are able to access the whole same rich API.

−

<code python>

+

<syntaxhighlight lang="python">

import karamba, Kross

import karamba, Kross

Line 355:

Line 413:

karamba.setRichTextWidth(widget, richtext, 345)

karamba.setRichTextWidth(widget, richtext, 345)

karamba.redrawWidget(widget)

karamba.redrawWidget(widget)

−

</code>

+

</syntaxhighlight>

See also...

See also...

Line 366:

Line 424:

The following python script shows how to use [http://www.riverbankcomputing.co.uk/pyqt/ PyQt] which provides the nice Qt-API pythonized. The sample just displays a "hello world" dialog if you click on the widget.

The following python script shows how to use [http://www.riverbankcomputing.co.uk/pyqt/ PyQt] which provides the nice Qt-API pythonized. The sample just displays a "hello world" dialog if you click on the widget.

−

<code python>

+

<syntaxhighlight lang="python">

import karamba

import karamba

from PyQt4 import QtCore, QtGui

from PyQt4 import QtCore, QtGui

Line 381:

Line 439:

dialog = Dialog()

dialog = Dialog()

dialog.exec_()

dialog.exec_()

−

</code>

+

</syntaxhighlight>

See also...

See also...

Line 391:

Line 449:

You are also able to use the default toolkit Python comes with, that is TkInter. The following sample just displays a TkInter "hello world" dialog if you click on the widget.

You are also able to use the default toolkit Python comes with, that is TkInter. The following sample just displays a TkInter "hello world" dialog if you click on the widget.

−

<code python>

+

<syntaxhighlight lang="python">

import karamba

import karamba

from Tkinter import *

from Tkinter import *

Line 400:

Line 458:

w.pack()

w.pack()

root.mainloop()

root.mainloop()

−

</code>

+

</syntaxhighlight>

See also...

See also...

Line 411:

Line 469:

The following sample script written in Ruby demonstrates that you are able to use [http://rubyforge.org/projects/korundum/ QtRuby/Korundum] within your Ruby scripts.

The following sample script written in Ruby demonstrates that you are able to use [http://rubyforge.org/projects/korundum/ QtRuby/Korundum] within your Ruby scripts.

−

<code ruby>

+

<syntaxhighlight lang="ruby">

require 'karamba'

require 'karamba'

require 'Qt'

require 'Qt'

Line 426:

Line 484:

dialog.exec

dialog.exec

end

end

−

</code>

+

</syntaxhighlight>

The script does implement only the widgetClicked function that got called if the user clicks on the widget. What we do within that function is to create an instance of the Dialog class that implements a QDialog using QtRuby and then execute that modal dialog.

The script does implement only the widgetClicked function that got called if the user clicks on the widget. What we do within that function is to create an instance of the Dialog class that implements a QDialog using QtRuby and then execute that modal dialog.

Line 438:

Line 496:

The following sample script written in Python just prints a list with services available via [http://dbus.freedesktop.org/ D-Bus];

The following sample script written in Python just prints a list with services available via [http://dbus.freedesktop.org/ D-Bus];

−

<code python>

+

<syntaxhighlight lang="python">

import karamba, dbus

import karamba, dbus

Line 454:

Line 512:

karamba.setRichTextWidth(widget, richtext, 500)

karamba.setRichTextWidth(widget, richtext, 500)

karamba.redrawWidget(widget)

karamba.redrawWidget(widget)

−

</code>

+

</syntaxhighlight>

−

While the following Python script uses [http://dbus.freedesktop.org/ D-Bus] to display a list with all the devices accessible with [http://www.freedesktop.org/wiki/Software/hal HAL];

+

The following Python script uses [http://dbus.freedesktop.org/ D-Bus] to display a list with all the devices accessible with [http://www.freedesktop.org/wiki/Software/hal HAL];

−

<code python>

+

<syntaxhighlight lang="python">

import karamba, dbus

import karamba, dbus

Line 474:

Line 532:

karamba.setRichTextWidth(widget, richtext, 500)

karamba.setRichTextWidth(widget, richtext, 500)

karamba.redrawWidget(widget)

karamba.redrawWidget(widget)

−

</code>

+

</syntaxhighlight>

While those both samples are going the most easy way to just synchronously call dbus functionality, you are also able to asynchronously call methods or just write a dbus-server by using the with python dbus supported Qt main event-loop as shown in the dbus-python tutorial below - but don't wonder that the samples printed there may not run since it seems the dbus-python module got largely refactored while the with it shipped documentation did not :-/

While those both samples are going the most easy way to just synchronously call dbus functionality, you are also able to asynchronously call methods or just write a dbus-server by using the with python dbus supported Qt main event-loop as shown in the dbus-python tutorial below - but don't wonder that the samples printed there may not run since it seems the dbus-python module got largely refactored while the with it shipped documentation did not :-/

Now lets take a more detailed look at a longer sample that uses SuperKaramba and the PlasmaApplet module. While the sample above runs in all cases, the following sample does not cause the used PlasmaApplet module will be only available if SuperKaramba is running as Plasma Applet. If you are running SuperKaramba as standalone application this wan't work (is there interest for this? - but both ways provide the same rich API functionality to work with Plasma::DataEngine's anyway).

+

+

<syntaxhighlight lang="python">

+

# Import the needed modules.

+

import karamba, PlasmaApplet

+

# Fetch the TimeEngine Plasma::DataEngine object.

+

engine = PlasmaApplet.dataEngine("time")

+

# We like to update it each second.

+

engine.setProperty("reportSeconds", True)

+

+

# Following lines are here to demonstrate that we are also able

+

# to dynamic handle the sources. It's not needed for this sample.

+

#def sourceAdded(source):

+

# print "sourceAdded '%s'" % source

+

#def sourceRemoved(source):

+

# print "sourceRemoved '%s'" % source

+

#def sourceUpdated(source,data):

+

# print "sourceUpdated '%s' '%s'" % (source,data)

+

#engine.connect("sourceAdded(QString)", sourceAdded)

+

#engine.connect("sourceRemoved(QString)", sourceRemoved)

+

#engine.connect("sourceUpdated(QString,QVariantMap)", sourceUpdated)

+

+

# Connect with the TimeEngine's source named "Local"

+

engine.connectSource("Local")

+

+

# This is the richedit widget we use to display something.

+

text = None

+

+

# This method just returns some text to display.

+

def getText():

+

t = "name: %s\n" % PlasmaApplet.name()

+

t += "category: %s\n" % PlasmaApplet.category()

+

t += "boundingRect: %s\n" % PlasmaApplet.boundingRect()

+

t += "sources: %s\n" % engine.sources()

+

t += "data: %s\n" % engine.query("Local")

+

return t

+

+

# This method got called by SuperKaramba on initialization.

+

def initWidget(widget):

+

global text

+

karamba.resizeWidget(widget, 400, 400)

+

text = karamba.createText(widget, 10, 10, 380, 380, getText())

+

karamba.redrawWidget(widget)

+

+

# This method got called by SuperKaramba on update.

+

def widgetUpdated(widget):

+

global text

+

karamba.changeText(widget, text, getText())

+

karamba.redrawWidget(widget)

+

</syntaxhighlight>

+

+

Following does the same as the sample above but connects the time Plasma::DataEngine with a meter-widget of SuperKaramba. The script will run once and compared to the sample above it's not needed to provide a widgetUpdated function but SuperKaramba will take care of updating the meter if the time Plasma::DataEngine provides new/updated data.

SuperKaramba is a tool that allows one to easily create functionality enhancement modules on a KDE desktop. Such modules are interactive programs written in Python, Ruby or KDE JavaScript that are usually embedded directly into the background and do not disturb the normal view of the desktop.

SuperKaramba does differ between 3 kind of elements. Commands define something that should be done (actions), meters are used to display something (GUI widgets) while sensors are to get something (data delivery).

A list of General Commands that you can put in your theme file. This includes tags that define the widget shape, set default fonts, and create click-areas that launch programs.

A list of Meters that you can put in your theme file. This includes meters display the values of sensors. Meters can auto-update.

A list of Sensors that you can put in your theme file. Sensors allow you to display system properties automatically. There are sensors to display the status of everything from memory use to the results of shell scripts. See here also the Plasma::DataEngine as SuperKaramba Sensor chapter.

Themes in SuperKaramba consist of two parts. A theme file that defines the shape and size of the theme, and possibly many other things and a script file that adds interactivity to the theme. Basically, whenever an event happens, such as the user clicking the mouse on your theme, a function is called in your script file to let you react to the event.

The simplest form of Karamba is to load a file containing the word karamba. This will give you a empty transparent window with the size 300x300. A better idea is to enter something like this in a file:

karamba x=30 y=30 w=400 h=200 interval=2000

This will bring up a window at 30,30 with the size 400x200, and the window will refresh every 2000 milliseconds = 2 seconds.

The graphics elements of Karamba are called meters. The meters can be connected to sensors. A sensor can get, e.g., the current CPU load, the uptime, the date, and a lot of other things. It is also possible to display the output of an external program in a meter.

Creating a meter is not that hard. A text label can be created by putting this line in the file:

text x=10 y=10 value="This is a test"

To add some more spice we connect a sensor to a meter:

text x=15 y=25 sensor=uptime

A graph that logs the CPU load can be made like this:

graph x=10 y=40 w=200 h=60 sensor=cpu

Adding an image (the path is either relative to the configuration file or an absolute path):

In Karamba all the graphic elements inside one configuration file have the same refresh rate. So it could be wise to split up a configuration into smaller parts, if different parts need different refresh times. An area showing a log file, for example, probably does not need the same refresh rate as an area showing the CPU load. The refresh rate of the sensors can be set individually.
Also Karamba does not work with backgrounds without a picture, i.e., solid color, gradient, or pattern. One can get around this bug by creating a transparent PNG image (the size can be 1x1 pixel) and selecting this as the background picture.

Now lets add interactivity to your theme file. If you have not written a theme file yet, you need to do that first like described at the "Creating the Theme File" chapter above. It will define the size, location on screen, and other basic elements of your theme.

Now that you have a basic theme file, load it with SuperKaramba. If there is nothing defined in the theme file other than size and location, you will have made an empty, transparent square that might be hard to find on the desktop.
Let's assume you have made a basic theme that just shows a few images in small area. To make your theme do anything interesting, it needs to be able to react to events.

Basically, an event is anything that can happen that SuperKaramba knows how to handle. Some examples are: the user moves or clicks the mouse, a new program is started on the desktop, a certain amount of time has passed, etc.
So to make your theme do something, you add Python or Ruby scripting code to the event callback that corresponds to the event to which you want to react. This is not nearly as hard as it sounds.

First, you need the template.py or the template.rb or the template.js template script file, depending on what scripting language you like to use. Download this file to where your theme file is. Now rename those just downloaded template file from template.py to mytheme.py or from template.rb to mytheme.rb where mytheme is the name of your theme. For example, if you wrote a coolbar.theme and like to use use Python, renamed the just downloaded template.py to coolbar.py and put it in the same directory as coolbar.theme.

Now, lets open up your coolbar.py (or coolbar.rb or whatever you named it to) scripting file. Look for the event callback that reacts to mouse movement. If you chose Python as your prefered scripting language, it may look like this:

Notice how the template gives your instructions on what data each callback gives you. In this case, you can see that you will know the x and y co-ordinates of the mouse, the button being held down (if any), and a reference to your widget.

Delete the line that says pass and add in some code. This code will run whenever the mouse is moved over your widget. But you say, "What in the world am I supposed to write to make something happen?". Good question! Go on to the next section below!

SuperKaramba has a powerful API (Application Programmer's Interface). This is just a fancy way of saying SuperKaramba has a bunch of special commands you can run from your Python or your Ruby scripting code to make something happen in your theme. All of the commands are listed in one big list:

This Python scripting code simply changes the text called "mouseText" (which we defined in our theme file) to tell us the current position of the mouse.

How did I know what parameters karamba.changeText() and karamba.getThemeText() used? How did I even know those functions existed in the first place? Well, thats what the API tells you. The API and the template.py or template.rb script file basically contain everything you could ever need to know to write your own theme.

To test your new Python or Ruby scripting code, just open your theme file in SuperKaramba.

You DO NOT open your .py or .rb file in SuperKaramba! Open the .theme file and if a matching .py or .rb file is found, it will be automatically loaded.

You DO NOT need to compile your scripting code. SuperKaramba will do that automatically and tell you about any errors. In fact, you can't run your .py or .rb file directly in regular python because it doesn't know anything about the karamba.* functions. Those functions only exist inside of SuperKaramba's Python and Ruby interpreters. But you are for sure able to just use SuperKaramba as your interpreter direct from within the commandline. Just start SuperKaramba with something like:

superkaramba ./coolbar.theme

To ease the development, SuperKaramba will automatically reload your theme when you save your changes to the theme file or the script file. This allows you to see your modifications immediately without reloading the theme manually.

While we were able to see a lot of rumours and speculations regarding SuperKaramba and it's role on KDE4, it's planned to continue to support SuperKaramba and it's unique feature-set, the bunches of themes that do already exist and those that will be written. We will stay backward-compatible and rocking stable, improve the feature-set as needed and wish you fun with the result: the next generation of SuperKaramba :)

SuperKaramba runs as standalonea-application - just run the program "superkaramba" - as well as Plasma Applet embedded into the Plasma Workspace. Also SuperKaramba provides full and transparent access to the Plasma::DataEngine's with it's sensor functionality.

The initWidget method will be called once if the widget got initialized. Here we setup the RichText widget where we display the current time in. The widgetUpdated will be called each second once (the interval is defined in the clock.theme themefile) and just updates the text display in the RichText widget with the new time.

Let's take a look at another theme. The text.py theme written in Python just displays some text widgets. We take this as example to create our own script, that does the same as the clock.rb above, that is to display the current time within a text widget.

In the initWidget method we create our text widget that is updated once per second (or per interval as defined in the matching theme file) at the widgetUpdated method to display the new current time.

The clock.js sample provides us with the same sample written using the JavaScript language.

There we have the currentTime() function that returns the current time as string. That function is used within the initWidget() and the widgetUpdated() functions to display the current time within a textwidget.

Modules are libraries loaded on demand provided by Kross. One of them is the forms module that implements some basic dialog and widget functionality. To display just a simple messagebox or load widgets from a UI-file those module can be used within all supported scripting languages.

The following sample Python script demonstrates how to display a messagebox.

Starting with Qt 4.4 and KDE 4.1 SuperKaramba is able to embed any kind of QWidgets into the canvas that is used to display something. That means, you are able to add a QLabel, a QPushButton or any other widget just direct into your Karambas.

The following python sample code, which is also available as webbrowser.py, demonstrates this by embedding a full webbrowser into your Karamba by using the CanvasWidget functionality.

#!/usr/bin/env superkaramba# coding: utf-8import karamba, Kross
khtml_part =Nonedef initWidget(widget):
# the Kross forms module does provide methods to create# widgets for us. You are for example able to load a UI# file, create layouts or just any other supported widget.
forms = Kross.module("forms")
frame = forms.createWidget("QWidget")
forms.createLayout(frame,"QHBoxLayout")# here we load the KHTML KPart that is our full powered# webbrowser widget.
khtml_part = forms.loadPart(frame,"libkhtmlpart")
khtml_part.javaScriptEnabled=True
khtml_part.javaEnabled=False
khtml_part.pluginsEnabled=False# now we add the frame to our widget and will earn a# proxywidget for it.
proxywidget = karamba.createCanvasWidget(widget, frame)# the following lines demonstrate, how to control the# webbrowser using the JavaScript language. The KHTML# KPart does provide different signals we are able to# connect our own functions too. Just see here the# kdelibs/khtml/khtmlpart.h file.def selectionChanged():
print khtml_part.executeScript("window.scrollBy(0,50);");
khtml_part.connect("selectionChanged()", selectionChanged)# and finally we like to load an url and display something.
khtml_part.openUrl("http://www.kde.org")def widgetClosed(widget):
# if the job is done, we may like to free our KPart again.if khtml_part:
khtml_part.delayedDestruct()

The following sample uses KSpread to read a OpenDocument spreadsheet file and to display it within a table.

For this we are loading the KSpread Scripting library and control it. Compared to dbus we don't need a running KSpread instance but just load and use the library direct (so, you still need to have KSpread installed).

While the sample is written in Python, the other supported backends like Ruby are able to access the whole same rich API.

The script does implement only the widgetClicked function that got called if the user clicks on the widget. What we do within that function is to create an instance of the Dialog class that implements a QDialog using QtRuby and then execute that modal dialog.

While those both samples are going the most easy way to just synchronously call dbus functionality, you are also able to asynchronously call methods or just write a dbus-server by using the with python dbus supported Qt main event-loop as shown in the dbus-python tutorial below - but don't wonder that the samples printed there may not run since it seems the dbus-python module got largely refactored while the with it shipped documentation did not :-/

You are also able to provide an own handle that defines what should be done if the Plasma::DataEngine has new or updated data for an widget or a meter.

# Import the SuperKaramba module.import karamba
# This method got called by SuperKaramba on initialization.def initWidget(widget):
karamba.resizeWidget(widget,400,400)# Create the text-widget (aka meter).
text = karamba.createText(widget,10,10,380,380)# Create the Plasma::DataEngine sensor.
engine = karamba.getPlasmaSensor(widget,"time","Local")# Connect the text-widget with the engine.
connector = engine.connectSource("Local", text)# An own handler for the connector.def func(source,data):
# Only display the current time but not the data["Date"].
karamba.changeText(widget, text, data["Time"])# Set empty source else the sourceUpdated() signal will not# be emitted.
connector.setSource("")# Connect the sourceUpdated() signal with the handler.
connector.connect("sourceUpdated(QString,QVariantMap)",func)

Now lets take a more detailed look at a longer sample that uses SuperKaramba and the PlasmaApplet module. While the sample above runs in all cases, the following sample does not cause the used PlasmaApplet module will be only available if SuperKaramba is running as Plasma Applet. If you are running SuperKaramba as standalone application this wan't work (is there interest for this? - but both ways provide the same rich API functionality to work with Plasma::DataEngine's anyway).

Following does the same as the sample above but connects the time Plasma::DataEngine with a meter-widget of SuperKaramba. The script will run once and compared to the sample above it's not needed to provide a widgetUpdated function but SuperKaramba will take care of updating the meter if the time Plasma::DataEngine provides new/updated data.

# Import the needed modules.import karamba, PlasmaApplet
# Fetch the TimeEngine Plasma::DataEngine object.
engine = PlasmaApplet.dataEngine("time")# We like to update it each second.
engine.setProperty("reportSeconds",True)# This method got called by SuperKaramba on initialization.def initWidget(widget):
global engine
karamba.resizeWidget(widget,400,400)# Create the text-meter widget.
text = karamba.createText(widget,10,10,380,380,"")# Connect the dataengine with the text-meter.
connector = engine.connectSource("Local", text)# Set the formatting. This is how the data should be# displayed. The local time-engine source provides the# '%Date' and the '%Time' values.
connector.setFormat('Date: %Date\nTime: %Time')# Following lines are here to demonstrate that you are also# able to implement an own handler for the connector.#def func(source,data):# karamba.changeText(widget, text, data["Time"])# Set empty source else the sourceUpdated() signal will not# be emitted.#connector.setSource("")# Connect the sourceUpdated() signal with the handler.#connector.connect("sourceUpdated(QString,QVariantMap)",func)
karamba.redrawWidget(widget)