<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="http://techbase.kde.org/skins/common/feed.css?0.2"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://techbase.kde.org/api.php?action=feedcontributions&amp;user=Hefee&amp;feedformat=atom</id>
		<title>KDE TechBase - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="http://techbase.kde.org/api.php?action=feedcontributions&amp;user=Hefee&amp;feedformat=atom"/>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Special:Contributions/Hefee"/>
		<updated>2013-05-24T01:39:44Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.20.2</generator>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials/Plasma/QML/API</id>
		<title>Development/Tutorials/Plasma/QML/API</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials/Plasma/QML/API"/>
				<updated>2013-02-06T00:57:49Z</updated>
		
		<summary type="html">&lt;p&gt;Hefee: /* Signals */  adding sample&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction to the Plasmoid QML Declarative API  =&lt;br /&gt;
&lt;br /&gt;
This document provides an overview/reference of the Declarative QML API for Plasmoids. It isn't a full binding to all of Qt or KDE's libraries, but a focused set of bindings designed to make writing Plasmoids fast and easy, while remaining powerful.&lt;br /&gt;
&lt;br /&gt;
The API in this documentation covers the API of the Plasma specific QML components, so only the Declarative part of the API.&lt;br /&gt;
&lt;br /&gt;
The QML ScriptEngine is based upon the Plasma JavaScript engine, making the API of the JavaScript part identical to the one of the JavaScript plasmoids engine.&lt;br /&gt;
To see the api of the global ''Plasmoid'' object, see the [http://techbase.kde.org/Development/Tutorials/Plasma/JavaScript/API#The_Global_plasmoid_Object JavaScript API] documentation.&lt;br /&gt;
(TODO: the JavaScript api page should probably be copied and stripped down the imperative bits not present there, it would make it harder to update tough)&lt;br /&gt;
The most important API for using graphical widgets is the [http://api.kde.org/4.x-api/plasma-qml-apidocs/ Plasma QtComponents API]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== What Is a Declarative Plasmoid?  ==&lt;br /&gt;
&lt;br /&gt;
To denote that this Plasmoid is a Declarative widget, ensure that in the metadata.desktop file there is this line: &lt;br /&gt;
&lt;br /&gt;
X-Plasma-API=declarativeappletscript&lt;br /&gt;
&lt;br /&gt;
What follows is a description of the Plasma declarative classes instantiable from QML.&lt;br /&gt;
&lt;br /&gt;
== fetching data from the plasmoid package ==&lt;br /&gt;
&lt;br /&gt;
If you have a file in your plasmoid package under contents, let's say an image, you can access it with the plasmapackage url protocol:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
Image {&lt;br /&gt;
    source: &amp;quot;plasmapackage:/images/foo.png&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above code will load in the Image component the file foo.png located in contents/images of your plasmoid package.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
import &amp;quot;plasmapackage:/code/foo.js&amp;quot; as Foo&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, the above code will import a javascript file from the folder contents/code of your plasmoid package.&lt;br /&gt;
&lt;br /&gt;
= Properties exported from the main QML item =&lt;br /&gt;
The root qml item can export some properties to influence its behavior:&lt;br /&gt;
* '''property int minimumWidth''': the plasmoid won't ever become narrower then that, size in pixels.&lt;br /&gt;
* '''property int minimumHeight''': minum height of the plasmoid, size in pixels.&lt;br /&gt;
* '''property Component compactRepresentation''': if the plasmoid is a popupapplet, the component in compactRepresentation will be used instead of the icon and will always be collapsed, regardless if it's in a panel or not.&lt;br /&gt;
&lt;br /&gt;
= Main Plasma QML Classes =&lt;br /&gt;
&lt;br /&gt;
== Data Engines ==&lt;br /&gt;
While it's possible to fetch data from a Plasma DataEngine in the same way as the [http://techbase.kde.org/Development/Tutorials/Plasma/JavaScript/API#DataEngine JavaScript API], it is preferrable to use the following declarative classes:&lt;br /&gt;
&lt;br /&gt;
=== DataSource ===&lt;br /&gt;
DataSource is a receiver for a dataEngine and can be declared inside QML:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 import org.kde.plasma.core 0.1 as PlasmaCore&lt;br /&gt;
&lt;br /&gt;
 PlasmaCore.DataSource {&lt;br /&gt;
     id: dataSource&lt;br /&gt;
     engine: &amp;quot;time&amp;quot;&lt;br /&gt;
     connectedSources: [&amp;quot;Local&amp;quot;]&lt;br /&gt;
     interval: 500&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Properties ====&lt;br /&gt;
It has the following properties:&lt;br /&gt;
* bool '''valid''' (read only): true when the DataSource is successfully connected to a data engine&lt;br /&gt;
* int '''interval''': interval of polling of the dataengine, if 0 (default value, so no need to specify if you don't need it) no polling will be executed&lt;br /&gt;
* string '''engine''': the plugin name of the dataengine to load, e.g. &amp;quot;nowplaying&amp;quot;, etc.&lt;br /&gt;
* Array(string) '''connectedSources''': all the sources of the dataengine we are connected to (and whose data will appear in the '''data''' property)&lt;br /&gt;
* Array(string) '''sources''' (read only): all the sources available from the dataengine&lt;br /&gt;
* variant map '''data''' (read only): It's the most important property, it's a map of all the data available from the dataengine: its structure will be as follows:&lt;br /&gt;
** each key of the map will be a source name, in '''connectedSources'''&lt;br /&gt;
** each value will be a variant hash, so an hash with strings as keys and any variant as value&lt;br /&gt;
** example: dataSource.data[&amp;quot;Local&amp;quot;][&amp;quot;Time&amp;quot;] indicates the '''Time''' key of the dataengine source called &amp;quot;Local&amp;quot;&lt;br /&gt;
* string '''sourceFilter''' it's a regular expression. If the DataSource is connected to more than one source, only inserts data from sources matching this filter expression in the model. If we want to have a source watch all sources beginning with say &amp;quot;name:&amp;quot;, the required regexp would be sourceFilter: &amp;quot;name:.*&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== Signals ====&lt;br /&gt;
It has the following signals:&lt;br /&gt;
&lt;br /&gt;
Note that javascript/qml applies the 'on' prefix to signals. So the actual signal name in C++ which is e.g. '''newData'''(...) becomes '''onNewData'''(...). &lt;br /&gt;
&lt;br /&gt;
* '''onNewData'''(String sourceName, Plasma::DataEngine::Data data) the local vairables are named to '''sourceName''' and '''data'''&lt;br /&gt;
* '''onSourceAdded'''(String source)&lt;br /&gt;
* '''onSourceRemoved'''(String source)&lt;br /&gt;
* '''onSourceConnected'''(String source)&lt;br /&gt;
* '''onSourceDisconnected'''(String source)&lt;br /&gt;
* '''onIntervalChanged'''()&lt;br /&gt;
* '''onEngineChanged'''()&lt;br /&gt;
* '''onDataChanged'''()&lt;br /&gt;
* '''onConnectedSourcesChanged'''()&lt;br /&gt;
* '''onSourcesChanged'''()&lt;br /&gt;
&lt;br /&gt;
You normaly wants to use '''onNewData''' (that is the aquivalent to '''dataUpdated''' in other languages). Here is sample with the time dataengine:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
import QtQuick 1.0&lt;br /&gt;
import org.kde.plasma.core 0.1 as PlasmaCore&lt;br /&gt;
&lt;br /&gt;
Item {&lt;br /&gt;
        PlasmaCore.DataSource {&lt;br /&gt;
                id: dataSource&lt;br /&gt;
                engine: &amp;quot;time&amp;quot;&lt;br /&gt;
                connectedSources: [&amp;quot;Local&amp;quot;,&amp;quot;UTC&amp;quot;]&lt;br /&gt;
                interval: 500&lt;br /&gt;
&lt;br /&gt;
                onNewData:{&lt;br /&gt;
                        if(sourceName== &amp;quot;Local&amp;quot;){&lt;br /&gt;
                                local.text = data.Time&lt;br /&gt;
                        }&lt;br /&gt;
                        else if(sourceName== &amp;quot;UTC&amp;quot;){&lt;br /&gt;
                                label_utc.text = data.Timezone&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
        Grid{&lt;br /&gt;
                columns: 2&lt;br /&gt;
                spacing: 5&lt;br /&gt;
                Text{text: dataSource.data.Local.Timezone}&lt;br /&gt;
                Text {&lt;br /&gt;
                        id: local&lt;br /&gt;
                        text: &amp;quot;XX:XX:XX&amp;quot;&lt;br /&gt;
                }&lt;br /&gt;
               Text{id: label_utc; text: &amp;quot;XXXX&amp;quot;}&lt;br /&gt;
               Text {&lt;br /&gt;
                       id: utc&lt;br /&gt;
                       text: dataSource.data.UTC.Time&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You see two different approches to get to the data:&lt;br /&gt;
&lt;br /&gt;
* One is to act on ''onNewData''&lt;br /&gt;
* Use the ''data'' parameter from dataSource&lt;br /&gt;
&lt;br /&gt;
==== Methods ====&lt;br /&gt;
It has the following methods:&lt;br /&gt;
* StringList keysForSource(String source): lists all the keys corresponding to a certain source: for instance in the &amp;quot;time&amp;quot; dataengine, for the &amp;quot;Local&amp;quot; source, keys will be:&lt;br /&gt;
** &amp;quot;Timezone Continent&amp;quot;&lt;br /&gt;
** &amp;quot;Offset&amp;quot;&lt;br /&gt;
** &amp;quot;Timezone&amp;quot;&lt;br /&gt;
** &amp;quot;Time&amp;quot;&lt;br /&gt;
** &amp;quot;Date&amp;quot;&lt;br /&gt;
** &amp;quot;Timezone City&amp;quot;&lt;br /&gt;
* Service serviceForSource(String source): returns a Plasma service that corresponds a given source: see the section about services for how to use it.&lt;br /&gt;
* void connectSource(String source): adds to '''connectedSources''' the new source&lt;br /&gt;
* void disconnectSource(String source): removes that source from '''connectedSources'''&lt;br /&gt;
&lt;br /&gt;
=== Service ===&lt;br /&gt;
Due to their imperative nature, Plasma Services are not instantiated as QML classes, but rather created out of a '''DataSource''' with the method '''serviceForSource''' and used in the JavaScript portions of the QML files.&lt;br /&gt;
This following example is a simplified version from the Now Playing QML widget in the kdeexamples git repository: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
  var service = dataSource.serviceForSource(activeSource)&lt;br /&gt;
  var operation = service.operationDescription(&amp;quot;seek&amp;quot;)&lt;br /&gt;
  operation.seconds = 10&lt;br /&gt;
&lt;br /&gt;
  var job = service.startOperationCall(operation)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Here dataSource is the id of a DataSource object, and activeSource is a source contained in one of its '''connectedSources'''.&lt;br /&gt;
The service provides an operation called &amp;quot;seek&amp;quot;, with a parameter called &amp;quot;seconds&amp;quot;, that can be written on it as a property of a JavaScript object.&lt;br /&gt;
&lt;br /&gt;
=== ServiceJob ===&lt;br /&gt;
It is necessary to monitor the result of a Service operation, it's possible to connect to the '''finished''' signal provided by the job return paramenter of the '''startOperationCall''' service method.&lt;br /&gt;
The '''finished''' signal has the same job as parameter, from which is possible to check the variant '''result''' property, to check the result.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    var service = messagesDataSource.serviceForSource(src)&lt;br /&gt;
    var operation = &amp;quot;auth&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    function result(job) {&lt;br /&gt;
        statusItem.authorizationStatus = job.result;&lt;br /&gt;
        print(&amp;quot;ServiceJob result: &amp;quot; + job.result + &amp;quot; op: &amp;quot; + job.operationName);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    var operation = service.operationDescription(operation);&lt;br /&gt;
    operation.user = userName;&lt;br /&gt;
    operation.password = password;&lt;br /&gt;
    var serviceJob = service.startOperationCall(operation);&lt;br /&gt;
    serviceJob.finished.connect(result);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== DataModel ===&lt;br /&gt;
Some data engines return as their data something that can be interpreted as a list of items, rather than simple key/value pairs.&lt;br /&gt;
QML provides some item views such as '''ListView''', '''GridView''' and '''Repeater'''.&lt;br /&gt;
The '''DataModel''' QML object can provide, based on a DataSource a model suitable for those QML item views.&lt;br /&gt;
&lt;br /&gt;
It has the following properties:&lt;br /&gt;
* DataSource '''dataSource''': the id of an existing (and connected) DataSource&lt;br /&gt;
* String '''sourceFilter''': it's a regular expression. If the DataSource is connected to more than one source, only inserts data from sources matching this filter expression in the model. To, for example, have a source watch all sources beginning with say &amp;quot;name:&amp;quot;, the required regexp would be sourceFilter: &amp;quot;name:.*&amp;quot;&lt;br /&gt;
* String '''keyRoleFilter''': it's a regular expression. Only data with keys that match this filter expression will be inserted in the model. If you need all data inserted in the mode, you must explicitly request it using the regular expression &amp;quot;.*&amp;quot;&lt;br /&gt;
* int '''count''' (read only): how many items are in the model&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 ListView {&lt;br /&gt;
   model: PlasmaCore.DataModel {&lt;br /&gt;
        dataSource: microblogSource&lt;br /&gt;
        keyRoleFilter: &amp;quot;[\\d]*&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
    delegate: Text {&lt;br /&gt;
        text: title&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the example, ''microblogSource'' is the id of a DataSource, and inserts in the model only entries that have a number as the key name (matched with [\\d]*, in this case tweets ids)&lt;br /&gt;
&lt;br /&gt;
Each item in the model will have the form of a variant hash: all the keys of the hash will be registered as model role names, in the example, &amp;quot;title&amp;quot; is a role of the model containing a string (also reachable with model[&amp;quot;title&amp;quot;]).&lt;br /&gt;
&lt;br /&gt;
A special reserved role will always be present: '''&amp;quot;DataEngineSource&amp;quot;''': it will contain the name of the data engine source that gave origin to this item. Therefore, if you want merely the string of the current source that the model is at...do model[&amp;quot;DataEngineSource&amp;quot;].&lt;br /&gt;
&lt;br /&gt;
Note that view.currentItem holds the item currently selected. However, due to (http://bugreports.qt.nokia.com/browse/QTBUG-16347) this does not work in PathView. A workaround is to make your own.&lt;br /&gt;
&lt;br /&gt;
=== SortFilterModel ===&lt;br /&gt;
SortFilterModel is a proxy model for easy sorting and/or filtering of the items in a DataModel (or any other QAbstractItemModel subclass that has been registered in QML with setContextProperty from a C++ application)&lt;br /&gt;
Properties:&lt;br /&gt;
* model '''sourceModel'''&lt;br /&gt;
* String '''filterRegExp'''&lt;br /&gt;
* String '''filterRole'''&lt;br /&gt;
* String '''sortRole'''&lt;br /&gt;
* Qt::SortOrder '''sortOrder'''&lt;br /&gt;
* int '''count''' (read only)&lt;br /&gt;
&lt;br /&gt;
This is an example from the feed widget:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
model: PlasmaCore.SortFilterModel {&lt;br /&gt;
   id: postTitleFilter&lt;br /&gt;
   filterRole: &amp;quot;title&amp;quot;&lt;br /&gt;
   sortRole: &amp;quot;time&amp;quot;&lt;br /&gt;
   sortOrder: &amp;quot;DescendingOrder&amp;quot;&lt;br /&gt;
   filterRegExp: toolbarFrame.searchQuery&lt;br /&gt;
   sourceModel: PlasmaCore.SortFilterModel {&lt;br /&gt;
      id: feedCategoryFilter&lt;br /&gt;
      filterRole: &amp;quot;feed_url&amp;quot;&lt;br /&gt;
      sourceModel: PlasmaCore.DataModel {&lt;br /&gt;
         dataSource: feedSource&lt;br /&gt;
         keyRoleFilter: &amp;quot;items&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Popup Applet ==&lt;br /&gt;
So you want your QML applet to be a popup applet, like the device notifier (an icon in the panel shows and expands the applet)?&lt;br /&gt;
&lt;br /&gt;
Why, that's easy.&lt;br /&gt;
&lt;br /&gt;
To change your plasmoid from being a regular boring one, in your '''metadata.desktop''', simply change this following line:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
ServiceTypes=Plasma/Applet&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
ServiceTypes=Plasma/Applet,Plasma/PopupApplet&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then in the main QML item's Component.onCompleted, do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
    plasmoid.popupIcon = &amp;quot;konqueror&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to use other elements instead of an icon when collapsed in a panel, use the '''compactRepresentation''' property in the root Item.&lt;br /&gt;
&lt;br /&gt;
== Plasma Themes ==&lt;br /&gt;
&lt;br /&gt;
=== Theme ===&lt;br /&gt;
This class instantiable from QML provides access to the Plasma Theme colors and other facilities such as fonts.&lt;br /&gt;
From KDE 4.8 a Theme instance is always present given the org.kde.plasma.core plugin was imported, is not necessary to create it by hand.&lt;br /&gt;
It has the following properties:&lt;br /&gt;
* String '''themeName''' (read only)&lt;br /&gt;
* bool '''windowTranslucentEnabled''' (read only)&lt;br /&gt;
* Url '''homepage''' (read only)&lt;br /&gt;
* bool '''useGlobalSettings''' (read only)&lt;br /&gt;
* QString '''wallpaperPath''' (read only)&lt;br /&gt;
* color '''textColor''' (read only)&lt;br /&gt;
* color '''highlightColor''' (read only)&lt;br /&gt;
* color '''backgroundColor''' (read only)&lt;br /&gt;
* color '''buttonTextColor''' (read only)&lt;br /&gt;
* color '''buttonBackgroundColor''' (read only)&lt;br /&gt;
* color '''linkColor''' (read only)&lt;br /&gt;
* color '''visitedLinkColor''' (read only)&lt;br /&gt;
* color '''visitedLinkColor''' (read only)&lt;br /&gt;
* color '''buttonHoverColor''' (read only)&lt;br /&gt;
* color '''buttonFocusColor''' (read only)&lt;br /&gt;
* color '''viewTextColor''' (read only)&lt;br /&gt;
* color '''viewBackgroundColor''' (read only)&lt;br /&gt;
* color '''viewHoverColor''' (read only)&lt;br /&gt;
* color '''viewFocusColor''' (read only)&lt;br /&gt;
* String '''styleSheet''' (read only)&lt;br /&gt;
* Font '''defaultFont''' (read only)&lt;br /&gt;
* Font '''desktopFont''' (read only)&lt;br /&gt;
* Font '''smallestFont''' (read only)&lt;br /&gt;
&lt;br /&gt;
Each Font element has the following properties:&lt;br /&gt;
* bool bold&lt;br /&gt;
* Capitalization '''capitalization''' (MixedCase, AllUppercase, AllLowercase, SmallCaps, Capitalize) (read only)&lt;br /&gt;
* String '''family''' (read only)&lt;br /&gt;
* bool '''italic''' (read only)&lt;br /&gt;
* real '''letterSpacing''' (read only)&lt;br /&gt;
* int '''pixelSize''' (read only)&lt;br /&gt;
* real '''pointSize''' (read only)&lt;br /&gt;
* bool '''strikeout''' (read only)&lt;br /&gt;
* bool '''underline''' (read only)&lt;br /&gt;
* Weight '''weight''' (Light, Normal, DemiBold, Bold, Black) (read only)&lt;br /&gt;
* real '''wordSpacing''' (read only)&lt;br /&gt;
* size '''mSize''' the size, width and height of an uppercase &amp;quot;M&amp;quot; in this font (read only)&lt;br /&gt;
&lt;br /&gt;
Theme is also used to control icon sizes, with the property '''iconSize'''. it is an Object, that has the following properties:&lt;br /&gt;
* int '''desktop''': size of icons suited for the workspace&lt;br /&gt;
* int '''toolbar''': icons to be put in a ToolBar component&lt;br /&gt;
* int '''small''': smallest size for still &amp;quot;readable&amp;quot; icons&lt;br /&gt;
* int '''dialog''': icons to be put in popup dialogs&lt;br /&gt;
&lt;br /&gt;
=== Svg ===&lt;br /&gt;
Declaring a Svg element instantiates a Plasma Svg instance. This class doesn't draw anything. For drawing, SvgItem is used.&lt;br /&gt;
Properties:&lt;br /&gt;
* QSize '''size'''&lt;br /&gt;
* bool '''multipleImages'''&lt;br /&gt;
* String '''imagePath''' can be anything in the '''desktoptheme/''' folder. For more information on what is available, see [http://techbase.kde.org/Projects/Plasma/Theme#Current_Theme_Elements Plasma Theme Elements]. Make sure to strip the final extension from this string, so you should for example use &amp;lt;code&amp;gt;&amp;quot;dialogs/background&amp;quot;&amp;lt;/code&amp;gt; to get the standard background.&lt;br /&gt;
* bool '''usingRenderingCache'''&lt;br /&gt;
&lt;br /&gt;
Methods:&lt;br /&gt;
* QPixmap pixmap(QString elementID)&lt;br /&gt;
* void resize(qreal width, qreal height)&lt;br /&gt;
* void resize(): resets the image to its default dimension&lt;br /&gt;
* QSize elementSize(QString elementId)&lt;br /&gt;
* QRectF elementRect(QString elementId)&lt;br /&gt;
* bool hasElement(QString elementId)&lt;br /&gt;
* bool isValid(): true if valid svg file&lt;br /&gt;
&lt;br /&gt;
=== FrameSvg ===&lt;br /&gt;
Declaring a FrameSvg element instantiates a Plasma FrameSvg instance. This class doesn't draw anything. For drawing, FrameSvgItem is used.&lt;br /&gt;
This is to be used when you need informations about the framesvg, such as hasElementPrefix().&lt;br /&gt;
&lt;br /&gt;
Properties:&lt;br /&gt;
* All properties from Svg&lt;br /&gt;
* EnabledBorders '''enabledBorders''': flag combination of:&lt;br /&gt;
** NoBorder&lt;br /&gt;
** TopBorder&lt;br /&gt;
** BottomBorder&lt;br /&gt;
** LeftBorder&lt;br /&gt;
** RightBorder&lt;br /&gt;
&lt;br /&gt;
Methods:&lt;br /&gt;
* All methods from Svg&lt;br /&gt;
* void setImagePath(QString path)&lt;br /&gt;
* void resizeFrame(QSize size)&lt;br /&gt;
* QSize frameSize()&lt;br /&gt;
* qreal marginSize(Plasma::MarginEdge edge)&lt;br /&gt;
* void getMargins(qreal left, qreal top, qreal right, qreal bottom): parameters are output, they get set with the margins from the FrameSvg&lt;br /&gt;
* QRectF contentsRect(): the rectangle of the center element, taking the margins into account.&lt;br /&gt;
* void setElementPrefix(QString prefix)&lt;br /&gt;
* bool hasElementPrefix(const QString prefix)&lt;br /&gt;
* QString prefix()&lt;br /&gt;
* void setCacheAllRenderedFrames(bool cache)&lt;br /&gt;
* bool cacheAllRenderedFrames()&lt;br /&gt;
* void clearCache()&lt;br /&gt;
* QPixmap framePixmap()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Sample Code:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
    PlasmaCore.FrameSvg {&lt;br /&gt;
        id: myFrameSvg&lt;br /&gt;
        imagePath: &amp;quot;widgets/button&amp;quot;&lt;br /&gt;
        prefix: &amp;quot;pressed&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== SvgItem ===&lt;br /&gt;
It's a graphical element that will actually paint a Svg instance.&lt;br /&gt;
Properties:&lt;br /&gt;
* String '''elementId''': what element to render. If null, the whole svg will be rendered&lt;br /&gt;
* Svg '''svg''': instance of the Svg class mentioned above&lt;br /&gt;
* QSizeF '''naturalSize''' (read only): default size of the Svg&lt;br /&gt;
* bool '''smooth''': paint with antialias (default false)&lt;br /&gt;
&lt;br /&gt;
Sample Code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
    PlasmaCore.SvgItem {&lt;br /&gt;
        id: mySvgItem&lt;br /&gt;
        anchors {&lt;br /&gt;
            top: parent.top&lt;br /&gt;
            left: parent.left&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        width: 300&lt;br /&gt;
        height: 3&lt;br /&gt;
&lt;br /&gt;
        svg: mySvg&lt;br /&gt;
        elementId: &amp;quot;horizontal-line&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== FrameSvgItem ===&lt;br /&gt;
It's a graphical element that paints a Plasma::FrameSvg, so a rectangular image composed by 9 elements contained in a Svg file, useful for things like buttons and frames.&lt;br /&gt;
&lt;br /&gt;
Flags&lt;br /&gt;
* EnabledBorders: combination of TopBorder | BottomBorder | LeftBorder | RightBorder, NoBorder if no border of the frame is enabled&lt;br /&gt;
&lt;br /&gt;
Properties:&lt;br /&gt;
* String '''imagePath''': path of the file relative to the Plasma Theme, for instance &amp;quot;widgets/background&amp;quot;&lt;br /&gt;
* String '''prefix''': a FrameSvg can contain multiple frames, for instance a button contains &amp;quot;normal&amp;quot;, &amp;quot;raised&amp;quot; and &amp;quot;pressed&amp;quot;&lt;br /&gt;
* Margins '''margins''' (read only): the margins of the frame, see documentation below&lt;br /&gt;
* EnabledBorders '''enabledBorders''': what borders are enabled&lt;br /&gt;
&lt;br /&gt;
==== Margins ====&lt;br /&gt;
Properties:&lt;br /&gt;
* real '''left''' (read only)&lt;br /&gt;
* real '''top''' (read only)&lt;br /&gt;
* real '''right''' (read only)&lt;br /&gt;
* real '''bottom''' (read only)&lt;br /&gt;
&lt;br /&gt;
Sample Code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
PlasmaCore.FrameSvgItem {&lt;br /&gt;
    id: myFrameSvgItem&lt;br /&gt;
    anchors.fill: parent&lt;br /&gt;
    imagePath: &amp;quot;translucent/dialogs/background&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Top Level windows ==&lt;br /&gt;
&lt;br /&gt;
=== Dialog ===&lt;br /&gt;
Dialog instantiates a Plasma::Dialog, it will be a Plasma themed top level window that can contain any QML component.&lt;br /&gt;
&lt;br /&gt;
Properties:&lt;br /&gt;
* Item '''mainItem''': the Item contained in the Dialog, it can be any QML Item instance&lt;br /&gt;
* bool '''visible''': if the window (not the mainItem) is visible&lt;br /&gt;
* int '''x''': x position of the window in screen coordinates&lt;br /&gt;
* int '''y''': y position of the window in screen coordinates&lt;br /&gt;
* int '''width''' (read only): total width of the dialog, including margins&lt;br /&gt;
* int '''height''' (read only): total height of the dialog, including margins.&lt;br /&gt;
* int '''windowFlags''': Qt window flags of the Dialog&lt;br /&gt;
* Margins '''margins''' (read only): margins of the Dialog&lt;br /&gt;
&lt;br /&gt;
{{Note|The width and height will scale with size of the main item within this Dialog component.}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
import QtQuick 1.1&lt;br /&gt;
import org.kde.plasma.core 0.1 as PlasmaCore&lt;br /&gt;
&lt;br /&gt;
Item {&lt;br /&gt;
    PlasmaCore.Dialog {&lt;br /&gt;
        visible: true&lt;br /&gt;
        mainItem: Item {&lt;br /&gt;
            width: 500&lt;br /&gt;
            height: 500&lt;br /&gt;
&lt;br /&gt;
            Text {&lt;br /&gt;
                anchors.centerIn: parent&lt;br /&gt;
                color: &amp;quot;red&amp;quot;&lt;br /&gt;
                text: qsTr(&amp;quot;text&amp;quot;)&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Methods:&lt;br /&gt;
* QPoint popupPosition(Item item, Qt::Alignment alignment=Qt::AlignLeft): the suggested position for the Dialog if it has to be correctly placed as popup of the QML item passed as parameter.&lt;br /&gt;
* void setAttribute(Qt::WindowAttribute attribute, bool on): set an attribute for the dialog window&lt;br /&gt;
&lt;br /&gt;
==== Margins ====&lt;br /&gt;
Properties:&lt;br /&gt;
* real '''left''' (read only)&lt;br /&gt;
* real '''top''' (read only)&lt;br /&gt;
* real '''right''' (read only)&lt;br /&gt;
* real '''bottom''' (read only)&lt;br /&gt;
&lt;br /&gt;
=== ToolTip ===&lt;br /&gt;
Declaring a ToolTip instance makes it possible to use Plasma tooltips with any QML item.&lt;br /&gt;
&lt;br /&gt;
Properties:&lt;br /&gt;
* Item '''target''': the QML item we want to show a tooltip of&lt;br /&gt;
* String '''mainText'''&lt;br /&gt;
* String '''subText'''&lt;br /&gt;
* String '''image''': freedesktop compliant icon name as image of the tooltip&lt;br /&gt;
&lt;br /&gt;
== Containments ==&lt;br /&gt;
A Plasma Containment manages the position and manipulation of Plasmoids. The declarative containment is responsible for layout of applets and can provide custom applet handles. The containment should listen to the plasmoid.immutability property. In order to lay out applets in your containment, you can use the AppletContainer class to access geometry information of applets.&lt;br /&gt;
Actions such as configure and close are available through plasmoid.actions.&lt;br /&gt;
You can access the plasmoid global property from containments in the same way as from declarative and javascript plasmoids. If the plasmoid is a Containment, you can get a list of actions for it. If you want to provide background rendering in your Containment yourself, read the applet.backgroundHints property and after that set applet.backgroundHints to 0 to tell the Applet that is should not render the background.&lt;br /&gt;
 &lt;br /&gt;
=== AppletContainer ===&lt;br /&gt;
The AppletContainer class provides access to the geometry and status of Plasmoids in this Containment.&lt;br /&gt;
Properties:&lt;br /&gt;
* ''Item'' '''applet''': The applet item, this property allows you to track destruction of the actual applet and update your layout.&lt;br /&gt;
** ''int'' '''backgroundHints''': Should the Applet be rendered on top of a background frame? 0 for no background, 1 for default background, 2 for translucent background&lt;br /&gt;
* ''int'' '''minimumWidth''': The minimum width of the applet&lt;br /&gt;
* ''int'' '''minimumHeight''': The minimum height of the applet&lt;br /&gt;
* ''int'' '''maximumWidth''': The maximum width of the applet&lt;br /&gt;
* ''int'' '''maximumHeight''': The maximum height of the applet&lt;br /&gt;
* ''int'' '''preferredWidth''': The preferred height of the applet&lt;br /&gt;
* ''int'' '''preferredHeight''': The preferred height of the applet&lt;br /&gt;
* ''enum'' '''status''': The status of the applet, one in the enum&lt;br /&gt;
** '''UnknownStatus''': The status is unknown&lt;br /&gt;
** '''PassiveStatus''': The applet is passive&lt;br /&gt;
** '''ActiveStatus''': The applet is active&lt;br /&gt;
** '''NeedsAttentionStatus''': The applet asks for attention&lt;br /&gt;
** '''AcceptingInputStatus''': The applet is accepting input&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
They can be imported in your code with:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
import org.kde.plasma.containments 0.1 as PlasmaContainments&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
AppletContainer is only available for Plasma/Containment packages, and only if they are loaded as containment. AppletContainer is new in 4.10.&lt;br /&gt;
&lt;br /&gt;
=== ToolBox ===&lt;br /&gt;
The ToolBox is only available through the plasmoid object, through plasmoid.toolBox(). The ToolBox is rendered as a separate item  on top of the scene covering the entire containment. It is loaded from the &amp;quot;org.kde.toolbox&amp;quot; Plasma Package, if the package is not found, no ToolBox will be loaded.&lt;br /&gt;
The ToolBox provides a listmodel of actions that can be rendered using Repeaters or ListViews. The ''actions'' list property contains actions from the Corona and Containments. Examples for these actions are showing the add widget or activities interface, lock and unlock. The actions in the list change dynamically whenever the widgets are locked or unlocked.&lt;br /&gt;
Actions such as lock screen and leave can be implemented using the powermanagement dataengine's services for these functions.&lt;br /&gt;
&lt;br /&gt;
ToolBox provides access to the following properties:&lt;br /&gt;
* ''Array(QAction)'' '''actions''': A list of actions provided by the Containment. These actions' most interesting properties are: &lt;br /&gt;
** ''QIcon'' '''icon''': The icon belonging to this action.&lt;br /&gt;
** ''String'' '''text''': The icon belonging to this action.&lt;br /&gt;
** '''trigger()''': Call trigger from your action delegate to trigger the action.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
import org.kde.plasma.containments 0.1 as PlasmaContainments&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ToolBox is only available for Containments and new in 4.10.&lt;br /&gt;
&lt;br /&gt;
= Plasma QtComponents (4.8) =&lt;br /&gt;
Plasma components documentation online at [http://api.kde.org/4.x-api/plasma-qml-apidocs/ api.kde.org]&lt;br /&gt;
&lt;br /&gt;
=QtExtraComponents=&lt;br /&gt;
The QtExtraComponents make some very convenient Qt classes usable from within QML.&lt;br /&gt;
&lt;br /&gt;
They can be imported in your code with:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
import org.kde.qtextracomponents 0.1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==QPixmapItem==&lt;br /&gt;
This one wraps around a QPixmap class and allows you to send a QPixmap directly to QPixmapItem.&lt;br /&gt;
 &lt;br /&gt;
Properties:&lt;br /&gt;
* QPixmap '''pixmap''': The QPixmap object.&lt;br /&gt;
* bool '''smooth''': Set to true to render smooth.&lt;br /&gt;
* int '''nativeWidth''': (verification needed) The QPixmap width&lt;br /&gt;
* int '''nativeHeight''': (verification needed) The QPixmap height&lt;br /&gt;
* FillMode '''fillMode''': see below&lt;br /&gt;
&lt;br /&gt;
==QImageItem==&lt;br /&gt;
This one wraps around a QImage class and allows you to send a QImage directly to QImageItem.&lt;br /&gt;
 &lt;br /&gt;
Properties:&lt;br /&gt;
* QImage '''image''': The QImage object.&lt;br /&gt;
* bool '''smooth''': Set to true to render smooth.&lt;br /&gt;
* int '''nativeWidth''': (verification needed) The QImage width&lt;br /&gt;
* int '''nativeHeight''': (verification needed) The QImage height&lt;br /&gt;
* FillMode '''fillMode''': see below&lt;br /&gt;
&lt;br /&gt;
==FillMode==&lt;br /&gt;
Both QPixmapItem and QImageItem expose a FillMode enum. This enum defines how the image is going to be used to fill the item.&lt;br /&gt;
&lt;br /&gt;
For QPixmapItem, possible values are:&lt;br /&gt;
&lt;br /&gt;
* QPixmapItem.Stretch: the image is scaled to fit&lt;br /&gt;
* QPixmapItem.PreserveAspectFit: the image is scaled uniformly to fit without cropping&lt;br /&gt;
* QPixmapItem.PreserveAspectCrop: the image is scaled uniformly to fill, cropping if necessary&lt;br /&gt;
* QPixmapItem.Tile: the image is duplicated horizontally and vertically&lt;br /&gt;
* QPixmapItem.TileVertically: the image is stretched horizontally and tiled vertically&lt;br /&gt;
* QPixmapItem.TileHorizontally :e image is stretched vertically and tiled horizontally&lt;br /&gt;
&lt;br /&gt;
QImageItem defines the same values, you just need to replace QPixmapItem with QImageItem.&lt;br /&gt;
&lt;br /&gt;
==QIconItem==&lt;br /&gt;
This one wraps around a QPixmap class and allows you to send a QIcon directly to QIconItem.&lt;br /&gt;
 &lt;br /&gt;
Properties:&lt;br /&gt;
* QIcon/QString '''icon''': If you provide a QIcon it uses that directly. If you provide a string it uses a KIcon internally!&lt;br /&gt;
* bool '''smooth''': Set to true to render smooth.&lt;br /&gt;
* int '''implicitWidth''': Default width of as set in SystemSettings-&amp;gt;Applications Appearance-&amp;gt;Icons&lt;br /&gt;
* int '''implicitHeight''': Default height of as set in SystemSettings-&amp;gt;Applications Appearance-&amp;gt;Icons&lt;br /&gt;
* State '''state''': Icon state (DefaultState, ActiveState, DisabledState)&lt;/div&gt;</summary>
		<author><name>Hefee</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials/Plasma/QML/GettingStarted</id>
		<title>Development/Tutorials/Plasma/QML/GettingStarted</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials/Plasma/QML/GettingStarted"/>
				<updated>2013-02-06T00:36:01Z</updated>
		
		<summary type="html">&lt;p&gt;Hefee: adding documentation to Row and Column&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Abstract ==&lt;br /&gt;
&lt;br /&gt;
Writing a plasma applet in QML is very easy, in fact, with KDE 4.6 and Qt 4.7 it just works.&lt;br /&gt;
&lt;br /&gt;
== QML Basics ==&lt;br /&gt;
&lt;br /&gt;
It is recommended that you have read through the [http://qt-project.org/doc/qt-4.8/qtquick.html Qt QML Tutorials], as there are quite a few and they are explained thoroughly. There is also a list of all [http://qt-project.org/doc/qt-4.8/qdeclarativeelements.html standard QML elements].&lt;br /&gt;
&lt;br /&gt;
Essentially, most of the content is the same. The exceptions to be noted are how data is gathered...since we use Data Engines, it is a bit different. Text color and font should be made to use PlasmaCore.Theme.&lt;br /&gt;
&lt;br /&gt;
See the [https://projects.kde.org/projects/kde/kdeexamples/repository KDE Examples] repository for more KDE-related helpful resources. Also of use (which use QML and Plasma) are: [https://projects.kde.org/projects/playground/base/plasma-mobile/repository Plasma Mobile], [https://projects.kde.org/projects/playground/base/declarative-plasmoids/repository Declarative Plasmoids (playground)], for WIP ports of C++ originals&lt;br /&gt;
&lt;br /&gt;
=== Root Item ===&lt;br /&gt;
&lt;br /&gt;
The root item can be anything that inherits QGraphicsItem. For example, in this case it is QGraphicsWidget which is a plasmoid. It can also simply be an Item. I also noticed that PathView does not respond to mouse inputs automatically (so flicking doesn't work). Probably because events are being intercepted. So take note, it'll have to be e.g. an Item, for that case.&lt;br /&gt;
&lt;br /&gt;
=== Layouts ===&lt;br /&gt;
&lt;br /&gt;
==== Row and Column ====&lt;br /&gt;
Coloums and Rows are very easy way to grouping items and is very simular to the &amp;quot;normal layout management&amp;quot; with [http://doc.qt.digia.com/stable/qhboxlayout.html QHBoxLayout] and [http://doc.qt.digia.com/stable/qvboxlayout.html  QVBoxLayout]. In QML these are named:&lt;br /&gt;
&lt;br /&gt;
* Column arranges its children in a column&lt;br /&gt;
* Row arranges its children in a row&lt;br /&gt;
* Grid arranges its children in a grid&lt;br /&gt;
* Flow arranges its children like words on a page&lt;br /&gt;
&lt;br /&gt;
They have a special property '''spacing'''(int) to define the distance in pixels between two children.&lt;br /&gt;
&lt;br /&gt;
For furture help please look at [http://qt-project.org/doc/qt-4.8/qml-positioners.html Using QML Positioner and Repeater Items from qt-project.org]&lt;br /&gt;
&lt;br /&gt;
Some example: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
import QtQuick 1.0&lt;br /&gt;
import org.kde.plasma.core 0.1 as PlasmaCore&lt;br /&gt;
&lt;br /&gt;
Item { &lt;br /&gt;
        Column{&lt;br /&gt;
                spacing: 10&lt;br /&gt;
                Row {  &lt;br /&gt;
                         spacing: 5&lt;br /&gt;
                        Text{text: 'Local'}&lt;br /&gt;
                        Text { &lt;br /&gt;
                                id: local&lt;br /&gt;
                                text: &amp;quot;XX:XX:XX&amp;quot;&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
                Row {  &lt;br /&gt;
                         spacing: 5&lt;br /&gt;
                        Text{text: 'UTC'}&lt;br /&gt;
                        Text { &lt;br /&gt;
                                id: utc&lt;br /&gt;
                                text: &amp;quot;XX:XX:XX&amp;quot;&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==== Anchors ====&lt;br /&gt;
Anchor layouts offer a nice way of grouping UI elements nicely together. The idea is that you connect edges or corners of one element to the edge or corner of another widget. Available anchors are:&lt;br /&gt;
* left&lt;br /&gt;
* horizontalCenter&lt;br /&gt;
* right&lt;br /&gt;
* top&lt;br /&gt;
* verticalCenter&lt;br /&gt;
* baseline, and bottom.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Some examples:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
import QtQuick 1.0&lt;br /&gt;
import org.kde.plasma.core 0.1 as PlasmaCore&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Item {&lt;br /&gt;
    width: 200&lt;br /&gt;
    height: 300&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    Text {&lt;br /&gt;
        id: first&lt;br /&gt;
        text: i18n(&amp;quot;1st line&amp;quot;)&lt;br /&gt;
        anchors { &lt;br /&gt;
            top: parent.top;&lt;br /&gt;
            left: parent.left;&lt;br /&gt;
            right: parent.right;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    Text {&lt;br /&gt;
        id: second&lt;br /&gt;
        text: i18n(&amp;quot;2nd line&amp;quot;)&lt;br /&gt;
        anchors {&lt;br /&gt;
            top: first.bottom;&lt;br /&gt;
            left: parent.left;&lt;br /&gt;
            right: parent.right;&lt;br /&gt;
            bottom: parent.bottom;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Keep in mind, that you can only use elements that are a parent or a sibling.&lt;br /&gt;
&lt;br /&gt;
Here a WRONG example ('first'' and ''second'' are no siblings ):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
    Text {&lt;br /&gt;
        id: first&lt;br /&gt;
        text: i18n(&amp;quot;1st line&amp;quot;)&lt;br /&gt;
    }&lt;br /&gt;
    Item{&lt;br /&gt;
         id: breakIt&lt;br /&gt;
        Text {&lt;br /&gt;
            id: second&lt;br /&gt;
            text: i18n(&amp;quot;2nd line&amp;quot;)&lt;br /&gt;
            anchors {&lt;br /&gt;
                 top: first.bottom;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Plasmoidviewer you show you folloing explanation:&lt;br /&gt;
&lt;br /&gt;
    file:///XXXX/contents/ui/main.qml:69:9: QML Text: Cannot anchor to an item that isn't a parent or sibling.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
More examples you will find on the  [http://qt-project.org/doc/qt-4.8/qml-anchor-layout.html Anchor-based Layout in QML from the qt-project.org].&lt;br /&gt;
&lt;br /&gt;
=== Buttons ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Animations ===&lt;br /&gt;
&lt;br /&gt;
== Package Structure ==&lt;br /&gt;
&lt;br /&gt;
You create a .desktop file and the .qml file. They have to be in the usual plasma package structure:&lt;br /&gt;
&lt;br /&gt;
* plasmoid-qml/metadata.desktop&lt;br /&gt;
* plasmoid-qml/contents/ui/main.qml&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;tt&amp;gt;metadata.desktop&amp;lt;/tt&amp;gt; ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
[Desktop Entry]&lt;br /&gt;
Name=Hello QML&lt;br /&gt;
Comment=A hello world widget in QML&lt;br /&gt;
Icon=chronometer&lt;br /&gt;
&lt;br /&gt;
X-Plasma-API=declarativeappletscript&lt;br /&gt;
X-Plasma-MainScript=ui/main.qml&lt;br /&gt;
X-Plasma-DefaultSize=200,100&lt;br /&gt;
&lt;br /&gt;
X-KDE-PluginInfo-Author=Frederik Gladhorn&lt;br /&gt;
X-KDE-PluginInfo-Email=gladhorn@kde.org&lt;br /&gt;
X-KDE-PluginInfo-Website=http://plasma.kde.org/&lt;br /&gt;
X-KDE-PluginInfo-Category=Examples&lt;br /&gt;
X-KDE-PluginInfo-Name=org.kde.hello-qml&lt;br /&gt;
X-KDE-PluginInfo-Version=0.0&lt;br /&gt;
&lt;br /&gt;
X-KDE-PluginInfo-Depends=&lt;br /&gt;
X-KDE-PluginInfo-License=GPL&lt;br /&gt;
X-KDE-PluginInfo-EnabledByDefault=true&lt;br /&gt;
X-KDE-ServiceTypes=Plasma/Applet&lt;br /&gt;
Type=Service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The line below indicates the default size of the plasmoid. The applet's starting size will be this, when added to a scene:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
X-Plasma-DefaultSize=200,100&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===  &amp;lt;tt&amp;gt;main.qml&amp;lt;/tt&amp;gt; ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
import QtQuick 1.0&lt;br /&gt;
&lt;br /&gt;
Text {&lt;br /&gt;
    text: &amp;quot;Hello world!&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Installing ==&lt;br /&gt;
You can install your plasmoid, though obviously this is just temporary. CMake, below, is recommended:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
plasmapkg --install plasmoid-qml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Installation through CMake ===&lt;br /&gt;
In your CMakeLists.txt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cmake&amp;quot;&amp;gt;&lt;br /&gt;
project(helloqml)&lt;br /&gt;
&lt;br /&gt;
find_package(KDE4 REQUIRED)&lt;br /&gt;
&lt;br /&gt;
include(KDE4Defaults)&lt;br /&gt;
&lt;br /&gt;
install(DIRECTORY package/&lt;br /&gt;
        DESTINATION ${DATA_INSTALL_DIR}/plasma/plasmoids/org.kde.plasma.applet.myapplet)&lt;br /&gt;
&lt;br /&gt;
install(FILES package/metadata.desktop&lt;br /&gt;
        DESTINATION ${SERVICES_INSTALL_DIR} RENAME plasma-applet-myapplet.desktop)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Your directory structure should now be as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
myproject/CMakeLists.txt&lt;br /&gt;
myproject/package/&lt;br /&gt;
myproject/package/metadata.desktop&lt;br /&gt;
myproject/package/contents/&lt;br /&gt;
myproject/package/contents/ui/&lt;br /&gt;
myproject/package/contents/ui/helloworld.qml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(if you have a configuration file (.ui file) to load the right-click 'plasmoid settings' menu, then your structure will also have myproject/package/contents/config/config.ui, or so)&lt;br /&gt;
&lt;br /&gt;
== plasmoidviewer ==&lt;br /&gt;
You can run it in plasmoidviewer as usual:&lt;br /&gt;
plasmoidviewer plasmoid-qml&lt;br /&gt;
&lt;br /&gt;
== qmlviewer ==&lt;br /&gt;
It's possible to use Plasma specific imports in qml files loaded by qmlviewer:&lt;br /&gt;
&lt;br /&gt;
qmlviewer -I /usr/lib/kde4/imports/ plasmoid-qml/contents/qml/main.qml &lt;br /&gt;
&lt;br /&gt;
Where the -I is the path to the plasma plugin for qml. Try to look for the path of &lt;br /&gt;
/usr/lib/kde4/imports/org/kde/plasma/graphicswidgets/libgraphicswidgetsbindingsplugin.so&lt;br /&gt;
and use everything up to org of that path.&lt;br /&gt;
&lt;br /&gt;
Hovewer it's '''strongly discouraged''' to use qmlviewer to develop plasmoids, because '''some features won't be available there, like the following''':&lt;br /&gt;
* localization with i18n()&lt;br /&gt;
* access to the global ''plasmoid'' object&lt;br /&gt;
* device specific qml files imported with plasmapackage:// urls&lt;br /&gt;
* bindings for qicons, KJobs, services and KConfig&lt;br /&gt;
* retrieving data from a DataEngine&lt;br /&gt;
&lt;br /&gt;
Therefore, it is recommended to simply use '''plasmoidviewer'''&lt;br /&gt;
&lt;br /&gt;
= Features only available in Plasma widgets =&lt;br /&gt;
In order to have a better integration with the KDE platform and to reach an higher degree of expressivity, the stock features of QML have been expanded with the following features, that strictly follow the Plasmoid JavaScript API:&lt;br /&gt;
&lt;br /&gt;
== Minimum size ==&lt;br /&gt;
if the root object of the plasmoid has the properties minimumWidth and minimumHeight, they will be used as the minimum size for the plasmoid. If they will change during the plasmoid execution, the plasmoid minimum size will be updated accordingly.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
import QtQuick 1.0&lt;br /&gt;
&lt;br /&gt;
Text {&lt;br /&gt;
    property int minimumWidth: paintedWidth&lt;br /&gt;
    property int minimumHeight: paintedHeight&lt;br /&gt;
    text: &amp;quot;Hello world!&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the above example, the minimum size is bound to the paintedWidth/paintedHeight properties of the Text element, ensuring there will always be enough room for the whole text to be displayed.&lt;br /&gt;
&lt;br /&gt;
== Plasmoid object ==&lt;br /&gt;
Every QML plasmoid will have an object called ''plasmoid'', that will give access to the configuration, the formfactor, immutability and so on. It offers the same api as the object with the same name in the Javascript API.&lt;br /&gt;
&lt;br /&gt;
For specific info on this, see [http://techbase.kde.org/Development/Tutorials/Plasma/JavaScript/API-PlasmoidObject Javascript API-Plasmoid Object]&lt;br /&gt;
&lt;br /&gt;
== Localization ==&lt;br /&gt;
It is possible to localize strings with the usual i18n(), i18nc(), i18np() global functions.&lt;br /&gt;
&lt;br /&gt;
== Extra types ==&lt;br /&gt;
Some extra types are available from withing JavaScript, namely&lt;br /&gt;
&lt;br /&gt;
* KConfigGroup: it's an object with its config keys readable and writable as properties&lt;br /&gt;
* QIcon: can be constructed with QIcon(&amp;quot;fdo name&amp;quot;) such as QIcon(&amp;quot;konqueror&amp;quot;)&lt;br /&gt;
* KJob&lt;br /&gt;
* Plasma Service api&lt;br /&gt;
&lt;br /&gt;
= Plasma specific imports =&lt;br /&gt;
To use some Plasma specific features and to take advantage of them in order for your applet to become a true Plasma applet, it is necessary to use some particular QML imports. See [http://techbase.kde.org/Development/Tutorials/Plasma/QML/API Plasma QML API].&lt;br /&gt;
&lt;br /&gt;
== Extra Qt features ==&lt;br /&gt;
org.kde.qtextraimports&lt;br /&gt;
To use, do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
import org.kde.qtextracomponents 0.1 as QtExtraComponents&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* QPixmapItem&lt;br /&gt;
* QImageItem&lt;br /&gt;
* QIconItem&lt;br /&gt;
&lt;br /&gt;
== Plasma Widgets in QML ==&lt;br /&gt;
To use standard plasma widgets (e.g. Plasma::LineEdit, etc.), you simply add an import line for them.&lt;br /&gt;
All properties, signals and slots from ordinary Plasma widgets are available there.&lt;br /&gt;
'''These widgets are provided as a transition tool, intended to be replaced by the Plasma version of QtComponents''', which is currently in development by a gsoc. (note that the Plasma QtComponents have nothing to do with the QtExtraComponents module described above)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
import QtQuick 1.0&lt;br /&gt;
import org.kde.plasma.graphicswidgets 0.1 as PlasmaWidgets&lt;br /&gt;
&lt;br /&gt;
Item {&lt;br /&gt;
    width: 64&lt;br /&gt;
    height: 64&lt;br /&gt;
    PlasmaWidgets.IconWidget {&lt;br /&gt;
        id: icon&lt;br /&gt;
        Component.onCompleted: setIcon(&amp;quot;flag-red&amp;quot;)&lt;br /&gt;
        anchors.centerIn: parent&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
To get a list of icons installed on system, run the command:&lt;br /&gt;
 $ kdialog --geticon actions&lt;/div&gt;</summary>
		<author><name>Hefee</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials/Plasma/QML/GettingStarted</id>
		<title>Development/Tutorials/Plasma/QML/GettingStarted</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials/Plasma/QML/GettingStarted"/>
				<updated>2013-02-06T00:12:30Z</updated>
		
		<summary type="html">&lt;p&gt;Hefee: /* Anchors */ adds a wrong example and points to the documenation of qt-project&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Abstract ==&lt;br /&gt;
&lt;br /&gt;
Writing a plasma applet in QML is very easy, in fact, with KDE 4.6 and Qt 4.7 it just works.&lt;br /&gt;
&lt;br /&gt;
== QML Basics ==&lt;br /&gt;
&lt;br /&gt;
It is recommended that you have read through the [http://qt-project.org/doc/qt-4.8/qtquick.html Qt QML Tutorials], as there are quite a few and they are explained thoroughly. There is also a list of all [http://qt-project.org/doc/qt-4.8/qdeclarativeelements.html standard QML elements].&lt;br /&gt;
&lt;br /&gt;
Essentially, most of the content is the same. The exceptions to be noted are how data is gathered...since we use Data Engines, it is a bit different. Text color and font should be made to use PlasmaCore.Theme.&lt;br /&gt;
&lt;br /&gt;
See the [https://projects.kde.org/projects/kde/kdeexamples/repository KDE Examples] repository for more KDE-related helpful resources. Also of use (which use QML and Plasma) are: [https://projects.kde.org/projects/playground/base/plasma-mobile/repository Plasma Mobile], [https://projects.kde.org/projects/playground/base/declarative-plasmoids/repository Declarative Plasmoids (playground)], for WIP ports of C++ originals&lt;br /&gt;
&lt;br /&gt;
=== Root Item ===&lt;br /&gt;
&lt;br /&gt;
The root item can be anything that inherits QGraphicsItem. For example, in this case it is QGraphicsWidget which is a plasmoid. It can also simply be an Item. I also noticed that PathView does not respond to mouse inputs automatically (so flicking doesn't work). Probably because events are being intercepted. So take note, it'll have to be e.g. an Item, for that case.&lt;br /&gt;
&lt;br /&gt;
=== Layouts ===&lt;br /&gt;
&lt;br /&gt;
==== Row and Column ====&lt;br /&gt;
&lt;br /&gt;
==== Anchors ====&lt;br /&gt;
Anchor layouts offer a nice way of grouping UI elements nicely together. The idea is that you connect edges or corners of one element to the edge or corner of another widget.&lt;br /&gt;
Some examples:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
import QtQuick 1.0&lt;br /&gt;
import org.kde.plasma.core 0.1 as PlasmaCore&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Item {&lt;br /&gt;
    width: 200&lt;br /&gt;
    height: 300&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    Text {&lt;br /&gt;
        id: first&lt;br /&gt;
        text: i18n(&amp;quot;1st line&amp;quot;)&lt;br /&gt;
        anchors { &lt;br /&gt;
            top: parent.top;&lt;br /&gt;
            left: parent.left;&lt;br /&gt;
            right: parent.right;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    Text {&lt;br /&gt;
        id: second&lt;br /&gt;
        text: i18n(&amp;quot;2nd line&amp;quot;)&lt;br /&gt;
        anchors {&lt;br /&gt;
            top: first.bottom;&lt;br /&gt;
            left: parent.left;&lt;br /&gt;
            right: parent.right;&lt;br /&gt;
            bottom: parent.bottom;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Keep in mind, that you can only use elements that are a parent or a sibling.&lt;br /&gt;
&lt;br /&gt;
Here a WRONG example ('first'' and ''second'' are no siblings ):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
    Text {&lt;br /&gt;
        id: first&lt;br /&gt;
        text: i18n(&amp;quot;1st line&amp;quot;)&lt;br /&gt;
    }&lt;br /&gt;
    Item{&lt;br /&gt;
         id: breakIt&lt;br /&gt;
        Text {&lt;br /&gt;
            id: second&lt;br /&gt;
            text: i18n(&amp;quot;2nd line&amp;quot;)&lt;br /&gt;
            anchors {&lt;br /&gt;
                 top: first.bottom;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Plasmoidviewer you show you folloing explanation:&lt;br /&gt;
&lt;br /&gt;
    file:///XXXX/contents/ui/main.qml:69:9: QML Text: Cannot anchor to an item that isn't a parent or sibling.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
More examples you will find on the  [http://qt-project.org/doc/qt-4.8/qml-anchor-layout.html Anchor-based Layout in QML from the qt-project].&lt;br /&gt;
&lt;br /&gt;
=== Buttons ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Animations ===&lt;br /&gt;
&lt;br /&gt;
== Package Structure ==&lt;br /&gt;
&lt;br /&gt;
You create a .desktop file and the .qml file. They have to be in the usual plasma package structure:&lt;br /&gt;
&lt;br /&gt;
* plasmoid-qml/metadata.desktop&lt;br /&gt;
* plasmoid-qml/contents/ui/main.qml&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;tt&amp;gt;metadata.desktop&amp;lt;/tt&amp;gt; ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
[Desktop Entry]&lt;br /&gt;
Name=Hello QML&lt;br /&gt;
Comment=A hello world widget in QML&lt;br /&gt;
Icon=chronometer&lt;br /&gt;
&lt;br /&gt;
X-Plasma-API=declarativeappletscript&lt;br /&gt;
X-Plasma-MainScript=ui/main.qml&lt;br /&gt;
X-Plasma-DefaultSize=200,100&lt;br /&gt;
&lt;br /&gt;
X-KDE-PluginInfo-Author=Frederik Gladhorn&lt;br /&gt;
X-KDE-PluginInfo-Email=gladhorn@kde.org&lt;br /&gt;
X-KDE-PluginInfo-Website=http://plasma.kde.org/&lt;br /&gt;
X-KDE-PluginInfo-Category=Examples&lt;br /&gt;
X-KDE-PluginInfo-Name=org.kde.hello-qml&lt;br /&gt;
X-KDE-PluginInfo-Version=0.0&lt;br /&gt;
&lt;br /&gt;
X-KDE-PluginInfo-Depends=&lt;br /&gt;
X-KDE-PluginInfo-License=GPL&lt;br /&gt;
X-KDE-PluginInfo-EnabledByDefault=true&lt;br /&gt;
X-KDE-ServiceTypes=Plasma/Applet&lt;br /&gt;
Type=Service&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The line below indicates the default size of the plasmoid. The applet's starting size will be this, when added to a scene:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
X-Plasma-DefaultSize=200,100&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===  &amp;lt;tt&amp;gt;main.qml&amp;lt;/tt&amp;gt; ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
import QtQuick 1.0&lt;br /&gt;
&lt;br /&gt;
Text {&lt;br /&gt;
    text: &amp;quot;Hello world!&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Installing ==&lt;br /&gt;
You can install your plasmoid, though obviously this is just temporary. CMake, below, is recommended:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
plasmapkg --install plasmoid-qml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Installation through CMake ===&lt;br /&gt;
In your CMakeLists.txt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cmake&amp;quot;&amp;gt;&lt;br /&gt;
project(helloqml)&lt;br /&gt;
&lt;br /&gt;
find_package(KDE4 REQUIRED)&lt;br /&gt;
&lt;br /&gt;
include(KDE4Defaults)&lt;br /&gt;
&lt;br /&gt;
install(DIRECTORY package/&lt;br /&gt;
        DESTINATION ${DATA_INSTALL_DIR}/plasma/plasmoids/org.kde.plasma.applet.myapplet)&lt;br /&gt;
&lt;br /&gt;
install(FILES package/metadata.desktop&lt;br /&gt;
        DESTINATION ${SERVICES_INSTALL_DIR} RENAME plasma-applet-myapplet.desktop)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Your directory structure should now be as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
myproject/CMakeLists.txt&lt;br /&gt;
myproject/package/&lt;br /&gt;
myproject/package/metadata.desktop&lt;br /&gt;
myproject/package/contents/&lt;br /&gt;
myproject/package/contents/ui/&lt;br /&gt;
myproject/package/contents/ui/helloworld.qml&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(if you have a configuration file (.ui file) to load the right-click 'plasmoid settings' menu, then your structure will also have myproject/package/contents/config/config.ui, or so)&lt;br /&gt;
&lt;br /&gt;
== plasmoidviewer ==&lt;br /&gt;
You can run it in plasmoidviewer as usual:&lt;br /&gt;
plasmoidviewer plasmoid-qml&lt;br /&gt;
&lt;br /&gt;
== qmlviewer ==&lt;br /&gt;
It's possible to use Plasma specific imports in qml files loaded by qmlviewer:&lt;br /&gt;
&lt;br /&gt;
qmlviewer -I /usr/lib/kde4/imports/ plasmoid-qml/contents/qml/main.qml &lt;br /&gt;
&lt;br /&gt;
Where the -I is the path to the plasma plugin for qml. Try to look for the path of &lt;br /&gt;
/usr/lib/kde4/imports/org/kde/plasma/graphicswidgets/libgraphicswidgetsbindingsplugin.so&lt;br /&gt;
and use everything up to org of that path.&lt;br /&gt;
&lt;br /&gt;
Hovewer it's '''strongly discouraged''' to use qmlviewer to develop plasmoids, because '''some features won't be available there, like the following''':&lt;br /&gt;
* localization with i18n()&lt;br /&gt;
* access to the global ''plasmoid'' object&lt;br /&gt;
* device specific qml files imported with plasmapackage:// urls&lt;br /&gt;
* bindings for qicons, KJobs, services and KConfig&lt;br /&gt;
* retrieving data from a DataEngine&lt;br /&gt;
&lt;br /&gt;
Therefore, it is recommended to simply use '''plasmoidviewer'''&lt;br /&gt;
&lt;br /&gt;
= Features only available in Plasma widgets =&lt;br /&gt;
In order to have a better integration with the KDE platform and to reach an higher degree of expressivity, the stock features of QML have been expanded with the following features, that strictly follow the Plasmoid JavaScript API:&lt;br /&gt;
&lt;br /&gt;
== Minimum size ==&lt;br /&gt;
if the root object of the plasmoid has the properties minimumWidth and minimumHeight, they will be used as the minimum size for the plasmoid. If they will change during the plasmoid execution, the plasmoid minimum size will be updated accordingly.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
import QtQuick 1.0&lt;br /&gt;
&lt;br /&gt;
Text {&lt;br /&gt;
    property int minimumWidth: paintedWidth&lt;br /&gt;
    property int minimumHeight: paintedHeight&lt;br /&gt;
    text: &amp;quot;Hello world!&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the above example, the minimum size is bound to the paintedWidth/paintedHeight properties of the Text element, ensuring there will always be enough room for the whole text to be displayed.&lt;br /&gt;
&lt;br /&gt;
== Plasmoid object ==&lt;br /&gt;
Every QML plasmoid will have an object called ''plasmoid'', that will give access to the configuration, the formfactor, immutability and so on. It offers the same api as the object with the same name in the Javascript API.&lt;br /&gt;
&lt;br /&gt;
For specific info on this, see [http://techbase.kde.org/Development/Tutorials/Plasma/JavaScript/API-PlasmoidObject Javascript API-Plasmoid Object]&lt;br /&gt;
&lt;br /&gt;
== Localization ==&lt;br /&gt;
It is possible to localize strings with the usual i18n(), i18nc(), i18np() global functions.&lt;br /&gt;
&lt;br /&gt;
== Extra types ==&lt;br /&gt;
Some extra types are available from withing JavaScript, namely&lt;br /&gt;
&lt;br /&gt;
* KConfigGroup: it's an object with its config keys readable and writable as properties&lt;br /&gt;
* QIcon: can be constructed with QIcon(&amp;quot;fdo name&amp;quot;) such as QIcon(&amp;quot;konqueror&amp;quot;)&lt;br /&gt;
* KJob&lt;br /&gt;
* Plasma Service api&lt;br /&gt;
&lt;br /&gt;
= Plasma specific imports =&lt;br /&gt;
To use some Plasma specific features and to take advantage of them in order for your applet to become a true Plasma applet, it is necessary to use some particular QML imports. See [http://techbase.kde.org/Development/Tutorials/Plasma/QML/API Plasma QML API].&lt;br /&gt;
&lt;br /&gt;
== Extra Qt features ==&lt;br /&gt;
org.kde.qtextraimports&lt;br /&gt;
To use, do:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
import org.kde.qtextracomponents 0.1 as QtExtraComponents&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* QPixmapItem&lt;br /&gt;
* QImageItem&lt;br /&gt;
* QIconItem&lt;br /&gt;
&lt;br /&gt;
== Plasma Widgets in QML ==&lt;br /&gt;
To use standard plasma widgets (e.g. Plasma::LineEdit, etc.), you simply add an import line for them.&lt;br /&gt;
All properties, signals and slots from ordinary Plasma widgets are available there.&lt;br /&gt;
'''These widgets are provided as a transition tool, intended to be replaced by the Plasma version of QtComponents''', which is currently in development by a gsoc. (note that the Plasma QtComponents have nothing to do with the QtExtraComponents module described above)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
import QtQuick 1.0&lt;br /&gt;
import org.kde.plasma.graphicswidgets 0.1 as PlasmaWidgets&lt;br /&gt;
&lt;br /&gt;
Item {&lt;br /&gt;
    width: 64&lt;br /&gt;
    height: 64&lt;br /&gt;
    PlasmaWidgets.IconWidget {&lt;br /&gt;
        id: icon&lt;br /&gt;
        Component.onCompleted: setIcon(&amp;quot;flag-red&amp;quot;)&lt;br /&gt;
        anchors.centerIn: parent&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
To get a list of icons installed on system, run the command:&lt;br /&gt;
 $ kdialog --geticon actions&lt;/div&gt;</summary>
		<author><name>Hefee</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Schedules</id>
		<title>Schedules</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Schedules"/>
				<updated>2011-02-08T23:39:42Z</updated>
		
		<summary type="html">&lt;p&gt;Hefee: /* KDE4 */ 4.7 Feature Plan&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&lt;br /&gt;
During development, the KDE project sets goals in features and dates for upcoming releases. This way, the team knows when it would be a good time to add a new feature or when it's time to&lt;br /&gt;
focus on cleaning up any bugs in preparation for a release. Any plans are tentative schedules and the final dates are generally decided on the kde-core-devel mailing list.&lt;br /&gt;
&lt;br /&gt;
Learn more about [[Schedules/Release Schedules Guide|release schedules]].&lt;br /&gt;
&lt;br /&gt;
== KDE4 ==&lt;br /&gt;
* [[Schedules/KDE4/Goals|KDE 4 Goals]]&lt;br /&gt;
* [[Schedules/KDE4/Application Porting Status|Application Porting Status]]&lt;br /&gt;
&lt;br /&gt;
*'''KDE SC 4.7'''&lt;br /&gt;
** [[Schedules/KDE4/4.7 Release Schedule|Release Schedule]]&lt;br /&gt;
** [[Schedules/KDE4/4.7 Feature Plan|Feature Plan]]&lt;br /&gt;
&lt;br /&gt;
*'''KDE SC 4.6'''&lt;br /&gt;
** [[Schedules/KDE4/4.6 Release Schedule|Release Schedule]]&lt;br /&gt;
** [[Schedules/KDE4/4.6 Feature Plan|Feature Plan]]&lt;br /&gt;
&lt;br /&gt;
*'''KDE SC 4.5'''&lt;br /&gt;
** [[Schedules/KDE4/4.5 Release Schedule|Release Schedule]]&lt;br /&gt;
** [[Schedules/KDE4/4.5 Feature Plan|Feature Plan]]&lt;br /&gt;
&lt;br /&gt;
*'''KDE SC 4.4'''&lt;br /&gt;
** [[Schedules/KDE4/4.4 Release Schedule|Release Schedule]]&lt;br /&gt;
** [[Schedules/KDE4/4.4 Release Goals|Release Goals]]&lt;br /&gt;
** [[Schedules/KDE4/4.4 Feature Plan|Feature Plan]]&lt;br /&gt;
** [[Schedules/Is KDE 4.4 for you?|Is KDE 4.4 for you?]]&lt;br /&gt;
** [[Schedules/KDE4/4.4 Upstream Issues|Release Critical Upstream Issues]]&lt;br /&gt;
** [[Schedules/KDE4/4.4 Requirements|Compilation Requirements]]&lt;br /&gt;
&lt;br /&gt;
*'''KDE 4.3'''&lt;br /&gt;
** [[Schedules/KDE4/4.3 Release Schedule|Release Schedule]]&lt;br /&gt;
** [[Schedules/KDE4/4.3 Release Goals|Release Goals]]&lt;br /&gt;
** [[Schedules/KDE4/4.3 Feature Plan|Feature Plan]]&lt;br /&gt;
** [[Schedules/Is KDE 4.3 for you?|Is KDE 4.3 for you?]]&lt;br /&gt;
** [[Schedules/KDE4/4.3 Upstream Issues|Release Critical Upstream Issues]]&lt;br /&gt;
** [[Schedules/KDE4/4.3 Requirements|Compilation Requirements]]&lt;br /&gt;
&lt;br /&gt;
*'''KDE 4.2'''&lt;br /&gt;
** [[Schedules/KDE4/4.2 Release Schedule|Release Schedule]]&lt;br /&gt;
** [[Schedules/KDE4/4.2 Release Goals|Release Goals]]&lt;br /&gt;
** [[Schedules/KDE4/4.2 Feature Plan|Feature Plan]]&lt;br /&gt;
** [[Schedules/Is KDE 4.2 for you?|Is KDE 4.2 for you?]]&lt;br /&gt;
** [[Schedules/KDE4/4.2 Upstream Issues|Release Critical Upstream Issues]]&lt;br /&gt;
** [[Schedules/KDE4/4.2 Requirements|Compilation Requirements]]&lt;br /&gt;
&lt;br /&gt;
*'''KDE 4.1'''&lt;br /&gt;
** [[Schedules/KDE4/4.1 Release Schedule|Release Schedule]]&lt;br /&gt;
** [[Schedules/KDE4/4.1 Release Goals|Release Goals]]&lt;br /&gt;
** [[Schedules/KDE4/4.1 Feature Plan|Feature Plan]]&lt;br /&gt;
** [[Schedules/Is KDE 4.1 for you?|Is KDE 4.1 for you?]]&lt;br /&gt;
&lt;br /&gt;
*'''KDE 4.0'''&lt;br /&gt;
** [[Schedules/KDE4/4.0 Release Schedule|Release Schedule]]&lt;br /&gt;
** [[Schedules/KDE4/4.0 Release Roadmap|Release Milestones]] &lt;br /&gt;
** [[Schedules/KDE4/4.0 Module_Status|Module Status and Pending Application Issues]]&lt;br /&gt;
** [[Schedules/KDE4/4.0 Upstream Issues|Release Critical Upstream Issues]]&lt;br /&gt;
** [[Schedules/KDE4/4.0 Announcements|Announcement Information]]&lt;br /&gt;
** [http://developer.kde.org/development-versions/kde-4.0-features.html Feature Plan]&lt;br /&gt;
** [[Schedules/KDE4/4.0 Requirements|Compilation Requirements]]&lt;br /&gt;
&lt;br /&gt;
== KDE3 ==&lt;br /&gt;
&lt;br /&gt;
*'''KDE 3.5''' [[Schedules/KDE 3.5 Release Schedule|release schedule]], [[Schedules/KDE 3.5 Feature Plan|feature plan]]&lt;br /&gt;
&lt;br /&gt;
=== Previous releases ===&lt;br /&gt;
&lt;br /&gt;
*'''KDE 3.4''' [[Schedules/KDE 3.4 Release Schedule|release schedule]], [[Schedules/KDE 3.4 Feature Plan|feature plan]]&lt;br /&gt;
*'''KDE 3.3''' [[Schedules/KDE 3.3 Release Schedule|release schedule]], [[Schedules/KDE 3.3 Feature Plan|feature plan]]&lt;br /&gt;
*'''KDE 3.2''' [[Schedules/KDE 3.2 Release Schedule|release schedule]], [[Schedules/KDE 3.2 Feature Plan|feature plan]]&lt;br /&gt;
*'''KDE 3.1''' [[Schedules/KDE 3.1 Release Schedule|release schedule]], [[Schedules/KDE 3.1 Feature Plan|feature plan]]&lt;br /&gt;
*'''KDE 3.0''' [[Schedules/KDE 3.0 Release Schedule|release schedule]], [[Schedules/KDE 3.0 Feature Plan|feature plan]]&lt;br /&gt;
&lt;br /&gt;
== KOffice ==&lt;br /&gt;
&lt;br /&gt;
=== Current releases ===&lt;br /&gt;
&lt;br /&gt;
*'''KOffice 2.3''' [http://wiki.koffice.org/index.php?title=Schedules/KOffice/2.3/Release_Plan release schedule], [http://wiki.koffice.org/index.php?title=Schedules/KOffice/2.3/Feature_Plan feature plan]&lt;br /&gt;
*'''KOffice 2.2''' [http://wiki.koffice.org/index.php?title=Schedules/KOffice/2.2/Release_Plan release schedule], [http://wiki.koffice.org/index.php?title=Schedules/KOffice/2.2/Feature_Plan feature plan]&lt;br /&gt;
*'''KOffice 2.1''' [http://wiki.koffice.org/index.php?title=Schedules/KOffice/2.1/Release_Plan release schedule], [http://wiki.koffice.org/index.php?title=Schedules/KOffice/2.1/Feature_Plan feature plan]&lt;br /&gt;
*'''KOffice 2.0''' [http://wiki.koffice.org/index.php?title=Schedules/KOffice/2.0/Release_Plan release schedule], [http://wiki.koffice.org/index.php?title=Schedules/KOffice/2.0/Feature_Plan feature plan]&lt;br /&gt;
&lt;br /&gt;
=== Previous releases ===&lt;br /&gt;
&lt;br /&gt;
*'''KOffice 1.6''' [[Schedules/KOffice 1.6 Release Schedule|release schedule]]&lt;br /&gt;
*'''KOffice 1.5''' [[Schedules/KOffice 1.5 Release Schedule|release schedule]]&lt;br /&gt;
&lt;br /&gt;
== Extragear ==&lt;br /&gt;
* [[Schedules/Extragear|Overview of upcoming Extragear releases]]&lt;br /&gt;
&lt;br /&gt;
== Playground ==&lt;br /&gt;
* [[Schedules/Playground|Overview of upcoming Playground releases]]&lt;/div&gt;</summary>
		<author><name>Hefee</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Languages/Python/PyKDE_Knotify_Tutorial/MyJob.py</id>
		<title>Development/Languages/Python/PyKDE Knotify Tutorial/MyJob.py</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Languages/Python/PyKDE_Knotify_Tutorial/MyJob.py"/>
				<updated>2010-08-10T00:12:01Z</updated>
		
		<summary type="html">&lt;p&gt;Hefee: Terimation&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;code python&amp;gt;&lt;br /&gt;
#! /usr/bin/python&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
from PyQt4.QtCore import QObject,QTimer,QString&lt;br /&gt;
from PyKDE4.kdecore import KJob&lt;br /&gt;
from PyKDE4.kio import KIO&lt;br /&gt;
 &lt;br /&gt;
class MyJob(KJob):&lt;br /&gt;
    def __init__(self,parent=QObject()):&lt;br /&gt;
        KJob.__init__(self,parent)&lt;br /&gt;
        #We want to have a Suspenable and Killable Job&lt;br /&gt;
        self.setCapabilities(KJob.Capabilities(KJob.Suspendable|KJob.Killable))&lt;br /&gt;
 &lt;br /&gt;
        #Just a maximum Variable&lt;br /&gt;
        self.max=25&lt;br /&gt;
 &lt;br /&gt;
        #index&lt;br /&gt;
        self.i=0&lt;br /&gt;
 &lt;br /&gt;
    def start(self):&lt;br /&gt;
        #register the Job to the JobTracker&lt;br /&gt;
        KIO.getJobTracker().registerJob(self)&lt;br /&gt;
&lt;br /&gt;
        #initalizing for work&lt;br /&gt;
        self.i=0&lt;br /&gt;
 &lt;br /&gt;
        #start the actual work in another thread&lt;br /&gt;
        #this function has to terminate, before the work is done&lt;br /&gt;
        QTimer().singleShot(0, self.doWork)&lt;br /&gt;
 &lt;br /&gt;
    def doWork(self):             &lt;br /&gt;
        #the actual work                                         &lt;br /&gt;
        try:            &lt;br /&gt;
            #if we are killed or suspended just return                                           &lt;br /&gt;
            if self.error() or self.isSuspended():                    &lt;br /&gt;
                return&lt;br /&gt;
        except RuntimeError:&lt;br /&gt;
            #if this class is killed before a RuntimeError will raise&lt;br /&gt;
            return&lt;br /&gt;
 &lt;br /&gt;
        #do a peace of hard work&lt;br /&gt;
        self.i+=1&lt;br /&gt;
 &lt;br /&gt;
        #fortunately we have made a peace of work &lt;br /&gt;
        #-&amp;gt; show this to everybody&lt;br /&gt;
        KJob.setPercent(self,self.i*4)&lt;br /&gt;
 &lt;br /&gt;
        if self.i==self.max:&lt;br /&gt;
            #jeah we have done the bunch of work&lt;br /&gt;
            #send the result signal for showing, that we ended the work&lt;br /&gt;
            self.emitResult()&lt;br /&gt;
            return &lt;br /&gt;
        #just go to sleep for 1000ms than go on&lt;br /&gt;
        QTimer().singleShot(1000, self.doWork)&lt;br /&gt;
 &lt;br /&gt;
    def doSuspend(self):&lt;br /&gt;
        #the surounding function from KJob makes the isSuspended() become True&lt;br /&gt;
        #returns True for signaling that this class supports to suspend&lt;br /&gt;
        return True&lt;br /&gt;
 &lt;br /&gt;
    def doResume(self):&lt;br /&gt;
        #start with work again&lt;br /&gt;
        QTimer().singleShot( 0, self.doWork )&lt;br /&gt;
        #return True for signaling that this class supports resuming&lt;br /&gt;
        return True&lt;br /&gt;
 &lt;br /&gt;
    def doKill(self):&lt;br /&gt;
        #return True for signaling that we support killing&lt;br /&gt;
        return True&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def handleResult(job):&lt;br /&gt;
    #handleResult Function&lt;br /&gt;
    #it is called when the job is terminating&lt;br /&gt;
    if job.error():&lt;br /&gt;
       print 'error happend'&lt;br /&gt;
    else:&lt;br /&gt;
       print 'job has terminated successfully'&lt;br /&gt;
    &lt;br /&gt;
    #termination the whole application&lt;br /&gt;
    sys.exit()&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    import sys&lt;br /&gt;
 &lt;br /&gt;
    from PyKDE4.kdecore import KCmdLineArgs, KAboutData, KLocalizedString, ki18n&lt;br /&gt;
    from PyKDE4.kdeui import KApplication    &lt;br /&gt;
 &lt;br /&gt;
    appName     = &amp;quot;default&amp;quot;&lt;br /&gt;
    catalog     = &amp;quot;&amp;quot;&lt;br /&gt;
    programName = ki18n (&amp;quot;default&amp;quot;)  &lt;br /&gt;
    version     = &amp;quot;1.0&amp;quot;&lt;br /&gt;
    description = ki18n (&amp;quot;Default Example&amp;quot;)  &lt;br /&gt;
    license     = KAboutData.License_GPL&lt;br /&gt;
    copyright   = ki18n (&amp;quot;(c) 2010 Sandro Knauß&amp;quot;) &lt;br /&gt;
    text        = ki18n (&amp;quot;none&amp;quot;) &lt;br /&gt;
    homePage    = &amp;quot;techbase.kde.org&amp;quot;&lt;br /&gt;
    bugEmail    = &amp;quot;bugs@sandroknauss.de&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    aboutData   = KAboutData (appName, catalog, programName, version, description,&lt;br /&gt;
                              license, copyright, text, homePage, bugEmail)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
    KCmdLineArgs.init (sys.argv, aboutData)&lt;br /&gt;
 &lt;br /&gt;
    app = KApplication ()&lt;br /&gt;
    &lt;br /&gt;
    #create job&lt;br /&gt;
    job=MyJob(app)&lt;br /&gt;
&lt;br /&gt;
    job.result.connect(handleResult)&lt;br /&gt;
&lt;br /&gt;
    #start job&lt;br /&gt;
    job.start()&lt;br /&gt;
    &lt;br /&gt;
    #wait till all is done&lt;br /&gt;
    app.exec_()&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Hefee</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Languages/Python/PyKDE_Knotify_Tutorial</id>
		<title>Development/Languages/Python/PyKDE Knotify Tutorial</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Languages/Python/PyKDE_Knotify_Tutorial"/>
				<updated>2010-08-10T00:10:51Z</updated>
		
		<summary type="html">&lt;p&gt;Hefee: terimation&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:I18n/Language Navigation Bar|Development/Languages/Python/PyKDE_Knotify_Tutorial}}&lt;br /&gt;
&lt;br /&gt;
{{TutorialBrowser|&lt;br /&gt;
&lt;br /&gt;
series=Python|&lt;br /&gt;
&lt;br /&gt;
name=Python KNotify Tutorial|&lt;br /&gt;
&lt;br /&gt;
next=|&lt;br /&gt;
&lt;br /&gt;
reading=[http://techbase.kde.org/Development/Tutorials/Python_introduction_to_signals_and_slots Qt Signals and Slots in python], [http://www.learningpython.com/2008/09/20/an-introduction-to-pyqt/ Introduction to PyQT4], [http://techbase.kde.org/Development/Languages/Python/Using_PyKDE_4 Using PyKDE4]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Abstract ==&lt;br /&gt;
&lt;br /&gt;
The aim of this tutorial is to give a sample class to include Notifications and Jobs to your own python programms, so the user can see what is going on (for example a backup system, that tells you that is backuping right now). It assumes a basic working knowledge of Python and PyKDE4. &lt;br /&gt;
For now only the Job part is mentioned, 'cause that is the only part I've created right now.&lt;br /&gt;
&lt;br /&gt;
== Further plans ==&lt;br /&gt;
To add the Notification part also to this tutorial.&lt;br /&gt;
&lt;br /&gt;
== Instruction ==&lt;br /&gt;
&lt;br /&gt;
We start with a minimal KDE Appliciation ([http://techbase.kde.org/Development/Languages/Python/Using_PyKDE_4 Using PyKDE4]):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code python&amp;gt;&lt;br /&gt;
#! /usr/bin/python&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    import sys&lt;br /&gt;
    &lt;br /&gt;
    from PyKDE4.kdecore import KCmdLineArgs, KAboutData, KLocalizedString, ki18n&lt;br /&gt;
    from PyKDE4.kdeui import KApplication    &lt;br /&gt;
    &lt;br /&gt;
    appName     = &amp;quot;default&amp;quot;&lt;br /&gt;
    catalog     = &amp;quot;&amp;quot;&lt;br /&gt;
    programName = ki18n (&amp;quot;default&amp;quot;)  &lt;br /&gt;
    version     = &amp;quot;1.0&amp;quot;&lt;br /&gt;
    description = ki18n (&amp;quot;Default Example&amp;quot;)  &lt;br /&gt;
    license     = KAboutData.License_GPL&lt;br /&gt;
    copyright   = ki18n (&amp;quot;(c) 2010 Sandro Knauß&amp;quot;) &lt;br /&gt;
    text        = ki18n (&amp;quot;none&amp;quot;) &lt;br /&gt;
    homePage    = &amp;quot;techbase.kde.org&amp;quot;&lt;br /&gt;
    bugEmail    = &amp;quot;bugs@sandroknauss.de&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    aboutData   = KAboutData (appName, catalog, programName, version, description,&lt;br /&gt;
                              license, copyright, text, homePage, bugEmail)&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    KCmdLineArgs.init (sys.argv, aboutData)&lt;br /&gt;
    &lt;br /&gt;
    app = KApplication ()&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Job class ==&lt;br /&gt;
The first step is to have a look to the [http://api.kde.org]. The intersting on is:&lt;br /&gt;
* [http://api.kde.org/pykde-4.3-api/kdecore/KJob.html KJob(KDE 4.3-PyKDE4)]- unfortunately this documention is only available for KDE 4.3. So we have also a look to the actual C++ Doumentation&lt;br /&gt;
* [http://api.kde.org/4.x-api/kdelibs-apidocs/kdecore/html/classKJob.html KJob(KJob 4.x-C++API)]&lt;br /&gt;
&lt;br /&gt;
So it is easy to write a small Job-Class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code python&amp;gt;&lt;br /&gt;
from PyQt4.QtCore import QObject,QTimer,QString&lt;br /&gt;
from PyKDE4.kdecore import KJob&lt;br /&gt;
&lt;br /&gt;
class MyJob(KJob):&lt;br /&gt;
    def __init__(self,parent=QObject()):&lt;br /&gt;
        KJob.__init__(self,parent)&lt;br /&gt;
        #We want to have a Suspenable and Killable Job&lt;br /&gt;
        self.setCapabilities(KJob.Capabilities(KJob.Suspendable|KJob.Killable))&lt;br /&gt;
&lt;br /&gt;
        #Just a maximum Variable&lt;br /&gt;
        self.max=25&lt;br /&gt;
&lt;br /&gt;
        #index&lt;br /&gt;
        self.i=0&lt;br /&gt;
&lt;br /&gt;
    def start(self):&lt;br /&gt;
        #initalizing for work&lt;br /&gt;
        self.i=0&lt;br /&gt;
       &lt;br /&gt;
        #start the actual work in another thread&lt;br /&gt;
        #this function has to terminate, before the work is done&lt;br /&gt;
        QTimer().singleShot(0, self.doWork)&lt;br /&gt;
                                                                                                                                               &lt;br /&gt;
    def doWork(self):             &lt;br /&gt;
        #the actual work                                         &lt;br /&gt;
        try:            &lt;br /&gt;
            #if we are killed or suspended just return                                           &lt;br /&gt;
            if self.error() or self.isSuspended():                    &lt;br /&gt;
                return&lt;br /&gt;
        except RuntimeError:&lt;br /&gt;
            #if this class is killed before a RuntimeError will raise&lt;br /&gt;
            return&lt;br /&gt;
&lt;br /&gt;
        #do a peace of hard work&lt;br /&gt;
        self.i+=1&lt;br /&gt;
&lt;br /&gt;
        #fortunately we have made a peace of work &lt;br /&gt;
        #-&amp;gt; show this to everybody&lt;br /&gt;
        KJob.setPercent(self,self.i*4)&lt;br /&gt;
       &lt;br /&gt;
        if self.i==self.max:&lt;br /&gt;
            #jeah we have done the bunch of work&lt;br /&gt;
            #send the result signal for showing, that we ended the work&lt;br /&gt;
            self.emitResult()&lt;br /&gt;
            return &lt;br /&gt;
        #just go to sleep for 1000ms than go on&lt;br /&gt;
        QTimer().singleShot(1000, self.doWork)&lt;br /&gt;
    &lt;br /&gt;
    def doSuspend(self):&lt;br /&gt;
        #the surounding function from KJob makes the isSuspended() become True&lt;br /&gt;
        #returns True for signaling that this class supports to suspend&lt;br /&gt;
        return True&lt;br /&gt;
&lt;br /&gt;
    def doResume(self):&lt;br /&gt;
        #start with work again&lt;br /&gt;
        QTimer().singleShot( 0, self.doWork )&lt;br /&gt;
        #return True for signaling that this class supports resuming&lt;br /&gt;
        return True&lt;br /&gt;
&lt;br /&gt;
    def doKill(self):&lt;br /&gt;
        #return True for signaling that we support killing&lt;br /&gt;
        return True&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===What is going on?===&lt;br /&gt;
* '''MyJob.__init__''': First we create the class and initialize the counter ''i'' and the maximum ''max''. To make is visible for others we set the Capacities, so this job is suspendable and killable.&lt;br /&gt;
* '''MyJob.start''': Here the pre working setting are made, we will se later for what we use this. After initalizing the Work we start the actual work by using a QTimer. The start method should start the asyncron.&lt;br /&gt;
* '''MyJob.doWork''': Do actual work and handle, if this job is killed or suspended.&lt;br /&gt;
* '''MyJob.doSuspend'''/'''MyJob.doResume'''/'''MyJob.doKill''': These function indicate that this feature is supported by this class.&lt;br /&gt;
&lt;br /&gt;
===How to use?===&lt;br /&gt;
Just create a instance of this class and start it:&lt;br /&gt;
&amp;lt;code python&amp;gt;&lt;br /&gt;
job=MyJob(app)&lt;br /&gt;
job.start()&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===We want to know when the jobs done?===&lt;br /&gt;
Create a '''SLOT''' to the '''result'''-signal:&lt;br /&gt;
&amp;lt;code python&amp;gt;&lt;br /&gt;
def handleResult(job):&lt;br /&gt;
    #handleResult Function&lt;br /&gt;
    #it is called when the job is terminating&lt;br /&gt;
    if job.error():&lt;br /&gt;
       print 'error happend'&lt;br /&gt;
    else:&lt;br /&gt;
       print 'job has terminated successfully'&lt;br /&gt;
    &lt;br /&gt;
    #for terimation the complete application&lt;br /&gt;
    sys.exit()&lt;br /&gt;
&lt;br /&gt;
job.result.connect(handleResult)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now we also add '''app.exec_()''' at the end of the main part, to prevent the program to stop before the job is stopped.&lt;br /&gt;
&lt;br /&gt;
===Visual feedback===&lt;br /&gt;
Till now, a normal user doesn't see anything what is going on. To change it we have to register the Job to a JobTracker.  Now a user will see a progressbar and a suspend and a stop button. So we modify the start method:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code python&amp;gt;&lt;br /&gt;
from PyKDE4.kio import KIO&lt;br /&gt;
...&lt;br /&gt;
    def start(self):&lt;br /&gt;
        #register the Job to the JobTracker&lt;br /&gt;
        KIO.getJobTracker().registerJob(self)&lt;br /&gt;
        self.i=0&lt;br /&gt;
        QTimer().singleShot(0, self.doWork)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Conclusion ===&lt;br /&gt;
Here is the [[Development/Languages/Python/PyKDE_Knotify_Tutorial/MyJob.py|full code]] of this example. &lt;br /&gt;
&lt;br /&gt;
Is is very easy to create a Job and make it visible to normal users. Unfortunately I have problems with setting the heading and description, so this will be added in later versions.&lt;/div&gt;</summary>
		<author><name>Hefee</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Languages/Python/PyKDE_Knotify_Tutorial/MyJob.py</id>
		<title>Development/Languages/Python/PyKDE Knotify Tutorial/MyJob.py</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Languages/Python/PyKDE_Knotify_Tutorial/MyJob.py"/>
				<updated>2010-08-09T23:56:13Z</updated>
		
		<summary type="html">&lt;p&gt;Hefee: Version 1.0&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&amp;lt;code python&amp;gt;&lt;br /&gt;
#! /usr/bin/python&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
from PyQt4.QtCore import QObject,QTimer,QString&lt;br /&gt;
from PyKDE4.kdecore import KJob&lt;br /&gt;
from PyKDE4.kio import KIO&lt;br /&gt;
 &lt;br /&gt;
class MyJob(KJob):&lt;br /&gt;
    def __init__(self,parent=QObject()):&lt;br /&gt;
        KJob.__init__(self,parent)&lt;br /&gt;
        #We want to have a Suspenable and Killable Job&lt;br /&gt;
        self.setCapabilities(KJob.Capabilities(KJob.Suspendable|KJob.Killable))&lt;br /&gt;
 &lt;br /&gt;
        #Just a maximum Variable&lt;br /&gt;
        self.max=25&lt;br /&gt;
 &lt;br /&gt;
        #index&lt;br /&gt;
        self.i=0&lt;br /&gt;
 &lt;br /&gt;
    def start(self):&lt;br /&gt;
        #register the Job to the JobTracker&lt;br /&gt;
        KIO.getJobTracker().registerJob(self)&lt;br /&gt;
&lt;br /&gt;
        #initalizing for work&lt;br /&gt;
        self.i=0&lt;br /&gt;
 &lt;br /&gt;
        #start the actual work in another thread&lt;br /&gt;
        #this function has to terminate, before the work is done&lt;br /&gt;
        QTimer().singleShot(0, self.doWork)&lt;br /&gt;
 &lt;br /&gt;
    def doWork(self):             &lt;br /&gt;
        #the actual work                                         &lt;br /&gt;
        try:            &lt;br /&gt;
            #if we are killed or suspended just return                                           &lt;br /&gt;
            if self.error() or self.isSuspended():                    &lt;br /&gt;
                return&lt;br /&gt;
        except RuntimeError:&lt;br /&gt;
            #if this class is killed before a RuntimeError will raise&lt;br /&gt;
            return&lt;br /&gt;
 &lt;br /&gt;
        #do a peace of hard work&lt;br /&gt;
        self.i+=1&lt;br /&gt;
 &lt;br /&gt;
        #fortunately we have made a peace of work &lt;br /&gt;
        #-&amp;gt; show this to everybody&lt;br /&gt;
        KJob.setPercent(self,self.i*4)&lt;br /&gt;
 &lt;br /&gt;
        if self.i==self.max:&lt;br /&gt;
            #jeah we have done the bunch of work&lt;br /&gt;
            #send the result signal for showing, that we ended the work&lt;br /&gt;
            self.emitResult()&lt;br /&gt;
            return &lt;br /&gt;
        #just go to sleep for 1000ms than go on&lt;br /&gt;
        QTimer().singleShot(1000, self.doWork)&lt;br /&gt;
 &lt;br /&gt;
    def doSuspend(self):&lt;br /&gt;
        #the surounding function from KJob makes the isSuspended() become True&lt;br /&gt;
        #returns True for signaling that this class supports to suspend&lt;br /&gt;
        return True&lt;br /&gt;
 &lt;br /&gt;
    def doResume(self):&lt;br /&gt;
        #start with work again&lt;br /&gt;
        QTimer().singleShot( 0, self.doWork )&lt;br /&gt;
        #return True for signaling that this class supports resuming&lt;br /&gt;
        return True&lt;br /&gt;
 &lt;br /&gt;
    def doKill(self):&lt;br /&gt;
        #return True for signaling that we support killing&lt;br /&gt;
        return True&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def handleResult(job):&lt;br /&gt;
    #handleResult Function&lt;br /&gt;
    #it is called when the job is terminating&lt;br /&gt;
    if job.error():&lt;br /&gt;
       print 'error happend'&lt;br /&gt;
    else:&lt;br /&gt;
       print 'job has terminated successfully'&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    import sys&lt;br /&gt;
 &lt;br /&gt;
    from PyKDE4.kdecore import KCmdLineArgs, KAboutData, KLocalizedString, ki18n&lt;br /&gt;
    from PyKDE4.kdeui import KApplication    &lt;br /&gt;
 &lt;br /&gt;
    appName     = &amp;quot;default&amp;quot;&lt;br /&gt;
    catalog     = &amp;quot;&amp;quot;&lt;br /&gt;
    programName = ki18n (&amp;quot;default&amp;quot;)  &lt;br /&gt;
    version     = &amp;quot;1.0&amp;quot;&lt;br /&gt;
    description = ki18n (&amp;quot;Default Example&amp;quot;)  &lt;br /&gt;
    license     = KAboutData.License_GPL&lt;br /&gt;
    copyright   = ki18n (&amp;quot;(c) 2010 Sandro Knauß&amp;quot;) &lt;br /&gt;
    text        = ki18n (&amp;quot;none&amp;quot;) &lt;br /&gt;
    homePage    = &amp;quot;techbase.kde.org&amp;quot;&lt;br /&gt;
    bugEmail    = &amp;quot;bugs@sandroknauss.de&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
    aboutData   = KAboutData (appName, catalog, programName, version, description,&lt;br /&gt;
                              license, copyright, text, homePage, bugEmail)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
    KCmdLineArgs.init (sys.argv, aboutData)&lt;br /&gt;
 &lt;br /&gt;
    app = KApplication ()&lt;br /&gt;
    &lt;br /&gt;
    #create job&lt;br /&gt;
    job=MyJob(app)&lt;br /&gt;
&lt;br /&gt;
    job.result.connect(handleResult)&lt;br /&gt;
&lt;br /&gt;
    #start job&lt;br /&gt;
    job.start()&lt;br /&gt;
    &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Hefee</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Languages/Python/PyKDE_Knotify_Tutorial</id>
		<title>Development/Languages/Python/PyKDE Knotify Tutorial</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Languages/Python/PyKDE_Knotify_Tutorial"/>
				<updated>2010-08-09T23:54:56Z</updated>
		
		<summary type="html">&lt;p&gt;Hefee: /* Job class */ KDE 4.3&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:I18n/Language Navigation Bar|Development/Languages/Python/PyKDE_Knotify_Tutorial}}&lt;br /&gt;
&lt;br /&gt;
{{TutorialBrowser|&lt;br /&gt;
&lt;br /&gt;
series=Python|&lt;br /&gt;
&lt;br /&gt;
name=Python KNotify Tutorial|&lt;br /&gt;
&lt;br /&gt;
next=|&lt;br /&gt;
&lt;br /&gt;
reading=[http://techbase.kde.org/Development/Tutorials/Python_introduction_to_signals_and_slots Qt Signals and Slots in python], [http://www.learningpython.com/2008/09/20/an-introduction-to-pyqt/ Introduction to PyQT4], [http://techbase.kde.org/Development/Languages/Python/Using_PyKDE_4 Using PyKDE4]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Abstract ==&lt;br /&gt;
&lt;br /&gt;
The aim of this tutorial is to give a sample class to include Notifications and Jobs to your own python programms, so the user can see what is going on (for example a backup system, that tells you that is backuping right now). It assumes a basic working knowledge of Python and PyKDE4. &lt;br /&gt;
For now only the Job part is mentioned, 'cause that is the only part I've created right now.&lt;br /&gt;
&lt;br /&gt;
== Further plans ==&lt;br /&gt;
To add the Notification part also to this tutorial.&lt;br /&gt;
&lt;br /&gt;
== Instruction ==&lt;br /&gt;
&lt;br /&gt;
We start with a minimal KDE Appliciation ([http://techbase.kde.org/Development/Languages/Python/Using_PyKDE_4 Using PyKDE4]):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code python&amp;gt;&lt;br /&gt;
#! /usr/bin/python&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    import sys&lt;br /&gt;
    &lt;br /&gt;
    from PyKDE4.kdecore import KCmdLineArgs, KAboutData, KLocalizedString, ki18n&lt;br /&gt;
    from PyKDE4.kdeui import KApplication    &lt;br /&gt;
    &lt;br /&gt;
    appName     = &amp;quot;default&amp;quot;&lt;br /&gt;
    catalog     = &amp;quot;&amp;quot;&lt;br /&gt;
    programName = ki18n (&amp;quot;default&amp;quot;)  &lt;br /&gt;
    version     = &amp;quot;1.0&amp;quot;&lt;br /&gt;
    description = ki18n (&amp;quot;Default Example&amp;quot;)  &lt;br /&gt;
    license     = KAboutData.License_GPL&lt;br /&gt;
    copyright   = ki18n (&amp;quot;(c) 2010 Sandro Knauß&amp;quot;) &lt;br /&gt;
    text        = ki18n (&amp;quot;none&amp;quot;) &lt;br /&gt;
    homePage    = &amp;quot;techbase.kde.org&amp;quot;&lt;br /&gt;
    bugEmail    = &amp;quot;bugs@sandroknauss.de&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    aboutData   = KAboutData (appName, catalog, programName, version, description,&lt;br /&gt;
                              license, copyright, text, homePage, bugEmail)&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    KCmdLineArgs.init (sys.argv, aboutData)&lt;br /&gt;
    &lt;br /&gt;
    app = KApplication ()&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Job class ==&lt;br /&gt;
The first step is to have a look to the [http://api.kde.org]. The intersting on is:&lt;br /&gt;
* [http://api.kde.org/pykde-4.3-api/kdecore/KJob.html KJob(KDE 4.3-PyKDE4)]- unfortunately this documention is only available for KDE 4.3. So we have also a look to the actual C++ Doumentation&lt;br /&gt;
* [http://api.kde.org/4.x-api/kdelibs-apidocs/kdecore/html/classKJob.html KJob(KJob 4.x-C++API)]&lt;br /&gt;
&lt;br /&gt;
So it is easy to write a small Job-Class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code python&amp;gt;&lt;br /&gt;
from PyQt4.QtCore import QObject,QTimer,QString&lt;br /&gt;
from PyKDE4.kdecore import KJob&lt;br /&gt;
&lt;br /&gt;
class MyJob(KJob):&lt;br /&gt;
    def __init__(self,parent=QObject()):&lt;br /&gt;
        KJob.__init__(self,parent)&lt;br /&gt;
        #We want to have a Suspenable and Killable Job&lt;br /&gt;
        self.setCapabilities(KJob.Capabilities(KJob.Suspendable|KJob.Killable))&lt;br /&gt;
&lt;br /&gt;
        #Just a maximum Variable&lt;br /&gt;
        self.max=25&lt;br /&gt;
&lt;br /&gt;
        #index&lt;br /&gt;
        self.i=0&lt;br /&gt;
&lt;br /&gt;
    def start(self):&lt;br /&gt;
        #initalizing for work&lt;br /&gt;
        self.i=0&lt;br /&gt;
       &lt;br /&gt;
        #start the actual work in another thread&lt;br /&gt;
        #this function has to terminate, before the work is done&lt;br /&gt;
        QTimer().singleShot(0, self.doWork)&lt;br /&gt;
                                                                                                                                               &lt;br /&gt;
    def doWork(self):             &lt;br /&gt;
        #the actual work                                         &lt;br /&gt;
        try:            &lt;br /&gt;
            #if we are killed or suspended just return                                           &lt;br /&gt;
            if self.error() or self.isSuspended():                    &lt;br /&gt;
                return&lt;br /&gt;
        except RuntimeError:&lt;br /&gt;
            #if this class is killed before a RuntimeError will raise&lt;br /&gt;
            return&lt;br /&gt;
&lt;br /&gt;
        #do a peace of hard work&lt;br /&gt;
        self.i+=1&lt;br /&gt;
&lt;br /&gt;
        #fortunately we have made a peace of work &lt;br /&gt;
        #-&amp;gt; show this to everybody&lt;br /&gt;
        KJob.setPercent(self,self.i*4)&lt;br /&gt;
       &lt;br /&gt;
        if self.i==self.max:&lt;br /&gt;
            #jeah we have done the bunch of work&lt;br /&gt;
            #send the result signal for showing, that we ended the work&lt;br /&gt;
            self.emitResult()&lt;br /&gt;
            return &lt;br /&gt;
        #just go to sleep for 1000ms than go on&lt;br /&gt;
        QTimer().singleShot(1000, self.doWork)&lt;br /&gt;
    &lt;br /&gt;
    def doSuspend(self):&lt;br /&gt;
        #the surounding function from KJob makes the isSuspended() become True&lt;br /&gt;
        #returns True for signaling that this class supports to suspend&lt;br /&gt;
        return True&lt;br /&gt;
&lt;br /&gt;
    def doResume(self):&lt;br /&gt;
        #start with work again&lt;br /&gt;
        QTimer().singleShot( 0, self.doWork )&lt;br /&gt;
        #return True for signaling that this class supports resuming&lt;br /&gt;
        return True&lt;br /&gt;
&lt;br /&gt;
    def doKill(self):&lt;br /&gt;
        #return True for signaling that we support killing&lt;br /&gt;
        return True&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===What is going on?===&lt;br /&gt;
* '''MyJob.__init__''': First we create the class and initialize the counter ''i'' and the maximum ''max''. To make is visible for others we set the Capacities, so this job is suspendable and killable.&lt;br /&gt;
* '''MyJob.start''': Here the pre working setting are made, we will se later for what we use this. After initalizing the Work we start the actual work by using a QTimer. The start method should start the asyncron.&lt;br /&gt;
* '''MyJob.doWork''': Do actual work and handle, if this job is killed or suspended.&lt;br /&gt;
* '''MyJob.doSuspend'''/'''MyJob.doResume'''/'''MyJob.doKill''': These function indicate that this feature is supported by this class.&lt;br /&gt;
&lt;br /&gt;
===How to use?===&lt;br /&gt;
Just create a instance of this class and start it:&lt;br /&gt;
&amp;lt;code python&amp;gt;&lt;br /&gt;
job=MyJob(app)&lt;br /&gt;
job.start()&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===We want to know when the jobs done?===&lt;br /&gt;
Create a '''SLOT''' to the '''result'''-signal:&lt;br /&gt;
&amp;lt;code python&amp;gt;&lt;br /&gt;
def handleResult(job):&lt;br /&gt;
    #handleResult Function&lt;br /&gt;
    #it is called when the job is terminating&lt;br /&gt;
    if job.error():&lt;br /&gt;
       print 'error happend'&lt;br /&gt;
    else:&lt;br /&gt;
       print 'job has terminated successfully'&lt;br /&gt;
&lt;br /&gt;
job.result.connect(handleResult)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Visual feedback===&lt;br /&gt;
Till now, a normal user doesn't see anything what is going on. To change it we have to register the Job to a JobTracker.  Now a user will see a progressbar and a suspend and a stop button. So we modify the start method:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code python&amp;gt;&lt;br /&gt;
from PyKDE4.kio import KIO&lt;br /&gt;
...&lt;br /&gt;
    def start(self):&lt;br /&gt;
        #register the Job to the JobTracker&lt;br /&gt;
        KIO.getJobTracker().registerJob(self)&lt;br /&gt;
        self.i=0&lt;br /&gt;
        QTimer().singleShot(0, self.doWork)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Conclusion ===&lt;br /&gt;
Here is the [[Development/Languages/Python/PyKDE_Knotify_Tutorial/MyJob.py|full code]] of this example. &lt;br /&gt;
&lt;br /&gt;
Is is very easy to create a Job and make it visible to normal users. Unfortunately I have problems with setting the heading and description, so this will be added in later versions.&lt;/div&gt;</summary>
		<author><name>Hefee</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Languages/Python/PyKDE_Knotify_Tutorial</id>
		<title>Development/Languages/Python/PyKDE Knotify Tutorial</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Languages/Python/PyKDE_Knotify_Tutorial"/>
				<updated>2010-08-09T23:50:32Z</updated>
		
		<summary type="html">&lt;p&gt;Hefee: /* Job class */ indent error&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:I18n/Language Navigation Bar|Development/Languages/Python/PyKDE_Knotify_Tutorial}}&lt;br /&gt;
&lt;br /&gt;
{{TutorialBrowser|&lt;br /&gt;
&lt;br /&gt;
series=Python|&lt;br /&gt;
&lt;br /&gt;
name=Python KNotify Tutorial|&lt;br /&gt;
&lt;br /&gt;
next=|&lt;br /&gt;
&lt;br /&gt;
reading=[http://techbase.kde.org/Development/Tutorials/Python_introduction_to_signals_and_slots Qt Signals and Slots in python], [http://www.learningpython.com/2008/09/20/an-introduction-to-pyqt/ Introduction to PyQT4], [http://techbase.kde.org/Development/Languages/Python/Using_PyKDE_4 Using PyKDE4]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Abstract ==&lt;br /&gt;
&lt;br /&gt;
The aim of this tutorial is to give a sample class to include Notifications and Jobs to your own python programms, so the user can see what is going on (for example a backup system, that tells you that is backuping right now). It assumes a basic working knowledge of Python and PyKDE4. &lt;br /&gt;
For now only the Job part is mentioned, 'cause that is the only part I've created right now.&lt;br /&gt;
&lt;br /&gt;
== Further plans ==&lt;br /&gt;
To add the Notification part also to this tutorial.&lt;br /&gt;
&lt;br /&gt;
== Instruction ==&lt;br /&gt;
&lt;br /&gt;
We start with a minimal KDE Appliciation ([http://techbase.kde.org/Development/Languages/Python/Using_PyKDE_4 Using PyKDE4]):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code python&amp;gt;&lt;br /&gt;
#! /usr/bin/python&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    import sys&lt;br /&gt;
    &lt;br /&gt;
    from PyKDE4.kdecore import KCmdLineArgs, KAboutData, KLocalizedString, ki18n&lt;br /&gt;
    from PyKDE4.kdeui import KApplication    &lt;br /&gt;
    &lt;br /&gt;
    appName     = &amp;quot;default&amp;quot;&lt;br /&gt;
    catalog     = &amp;quot;&amp;quot;&lt;br /&gt;
    programName = ki18n (&amp;quot;default&amp;quot;)  &lt;br /&gt;
    version     = &amp;quot;1.0&amp;quot;&lt;br /&gt;
    description = ki18n (&amp;quot;Default Example&amp;quot;)  &lt;br /&gt;
    license     = KAboutData.License_GPL&lt;br /&gt;
    copyright   = ki18n (&amp;quot;(c) 2010 Sandro Knauß&amp;quot;) &lt;br /&gt;
    text        = ki18n (&amp;quot;none&amp;quot;) &lt;br /&gt;
    homePage    = &amp;quot;techbase.kde.org&amp;quot;&lt;br /&gt;
    bugEmail    = &amp;quot;bugs@sandroknauss.de&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    aboutData   = KAboutData (appName, catalog, programName, version, description,&lt;br /&gt;
                              license, copyright, text, homePage, bugEmail)&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    KCmdLineArgs.init (sys.argv, aboutData)&lt;br /&gt;
    &lt;br /&gt;
    app = KApplication ()&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Job class ==&lt;br /&gt;
The first step is to have a look to the [http://api.kde.org]. The intersting on is:&lt;br /&gt;
* [http://api.kde.org/pykde-4.1-api/kdecore/KJob.html KJob(KDE 4.1-PyKDE4)]- unfortunately this documention is only available for KDE 4.1. So we have also a look to the actual C++ Doumentation&lt;br /&gt;
* [http://api.kde.org/4.x-api/kdelibs-apidocs/kdecore/html/classKJob.html KJob(KJob 4.x-C++API)]&lt;br /&gt;
&lt;br /&gt;
So it is easy to write a small Job-Class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code python&amp;gt;&lt;br /&gt;
from PyQt4.QtCore import QObject,QTimer,QString&lt;br /&gt;
from PyKDE4.kdecore import KJob&lt;br /&gt;
&lt;br /&gt;
class MyJob(KJob):&lt;br /&gt;
    def __init__(self,parent=QObject()):&lt;br /&gt;
        KJob.__init__(self,parent)&lt;br /&gt;
        #We want to have a Suspenable and Killable Job&lt;br /&gt;
        self.setCapabilities(KJob.Capabilities(KJob.Suspendable|KJob.Killable))&lt;br /&gt;
&lt;br /&gt;
        #Just a maximum Variable&lt;br /&gt;
        self.max=25&lt;br /&gt;
&lt;br /&gt;
        #index&lt;br /&gt;
        self.i=0&lt;br /&gt;
&lt;br /&gt;
    def start(self):&lt;br /&gt;
        #initalizing for work&lt;br /&gt;
        self.i=0&lt;br /&gt;
       &lt;br /&gt;
        #start the actual work in another thread&lt;br /&gt;
        #this function has to terminate, before the work is done&lt;br /&gt;
        QTimer().singleShot(0, self.doWork)&lt;br /&gt;
                                                                                                                                               &lt;br /&gt;
    def doWork(self):             &lt;br /&gt;
        #the actual work                                         &lt;br /&gt;
        try:            &lt;br /&gt;
            #if we are killed or suspended just return                                           &lt;br /&gt;
            if self.error() or self.isSuspended():                    &lt;br /&gt;
                return&lt;br /&gt;
        except RuntimeError:&lt;br /&gt;
            #if this class is killed before a RuntimeError will raise&lt;br /&gt;
            return&lt;br /&gt;
&lt;br /&gt;
        #do a peace of hard work&lt;br /&gt;
        self.i+=1&lt;br /&gt;
&lt;br /&gt;
        #fortunately we have made a peace of work &lt;br /&gt;
        #-&amp;gt; show this to everybody&lt;br /&gt;
        KJob.setPercent(self,self.i*4)&lt;br /&gt;
       &lt;br /&gt;
        if self.i==self.max:&lt;br /&gt;
            #jeah we have done the bunch of work&lt;br /&gt;
            #send the result signal for showing, that we ended the work&lt;br /&gt;
            self.emitResult()&lt;br /&gt;
            return &lt;br /&gt;
        #just go to sleep for 1000ms than go on&lt;br /&gt;
        QTimer().singleShot(1000, self.doWork)&lt;br /&gt;
    &lt;br /&gt;
    def doSuspend(self):&lt;br /&gt;
        #the surounding function from KJob makes the isSuspended() become True&lt;br /&gt;
        #returns True for signaling that this class supports to suspend&lt;br /&gt;
        return True&lt;br /&gt;
&lt;br /&gt;
    def doResume(self):&lt;br /&gt;
        #start with work again&lt;br /&gt;
        QTimer().singleShot( 0, self.doWork )&lt;br /&gt;
        #return True for signaling that this class supports resuming&lt;br /&gt;
        return True&lt;br /&gt;
&lt;br /&gt;
    def doKill(self):&lt;br /&gt;
        #return True for signaling that we support killing&lt;br /&gt;
        return True&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===What is going on?===&lt;br /&gt;
* '''MyJob.__init__''': First we create the class and initialize the counter ''i'' and the maximum ''max''. To make is visible for others we set the Capacities, so this job is suspendable and killable.&lt;br /&gt;
* '''MyJob.start''': Here the pre working setting are made, we will se later for what we use this. After initalizing the Work we start the actual work by using a QTimer. The start method should start the asyncron.&lt;br /&gt;
* '''MyJob.doWork''': Do actual work and handle, if this job is killed or suspended.&lt;br /&gt;
* '''MyJob.doSuspend'''/'''MyJob.doResume'''/'''MyJob.doKill''': These function indicate that this feature is supported by this class.&lt;br /&gt;
&lt;br /&gt;
===How to use?===&lt;br /&gt;
Just create a instance of this class and start it:&lt;br /&gt;
&amp;lt;code python&amp;gt;&lt;br /&gt;
job=MyJob(app)&lt;br /&gt;
job.start()&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===We want to know when the jobs done?===&lt;br /&gt;
Create a '''SLOT''' to the '''result'''-signal:&lt;br /&gt;
&amp;lt;code python&amp;gt;&lt;br /&gt;
def handleResult(job):&lt;br /&gt;
    #handleResult Function&lt;br /&gt;
    #it is called when the job is terminating&lt;br /&gt;
    if job.error():&lt;br /&gt;
       print 'error happend'&lt;br /&gt;
    else:&lt;br /&gt;
       print 'job has terminated successfully'&lt;br /&gt;
&lt;br /&gt;
job.result.connect(handleResult)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Visual feedback===&lt;br /&gt;
Till now, a normal user doesn't see anything what is going on. To change it we have to register the Job to a JobTracker.  Now a user will see a progressbar and a suspend and a stop button. So we modify the start method:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code python&amp;gt;&lt;br /&gt;
from PyKDE4.kio import KIO&lt;br /&gt;
...&lt;br /&gt;
    def start(self):&lt;br /&gt;
        #register the Job to the JobTracker&lt;br /&gt;
        KIO.getJobTracker().registerJob(self)&lt;br /&gt;
        self.i=0&lt;br /&gt;
        QTimer().singleShot(0, self.doWork)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Conclusion ===&lt;br /&gt;
Here is the [[Development/Languages/Python/PyKDE_Knotify_Tutorial/MyJob.py|full code]] of this example. &lt;br /&gt;
&lt;br /&gt;
Is is very easy to create a Job and make it visible to normal users. Unfortunately I have problems with setting the heading and description, so this will be added in later versions.&lt;/div&gt;</summary>
		<author><name>Hefee</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Languages/Python/PyKDE_Knotify_Tutorial</id>
		<title>Development/Languages/Python/PyKDE Knotify Tutorial</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Languages/Python/PyKDE_Knotify_Tutorial"/>
				<updated>2010-08-09T23:40:10Z</updated>
		
		<summary type="html">&lt;p&gt;Hefee: How to use/Visible feed/Conclusion&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:I18n/Language Navigation Bar|Development/Languages/Python/PyKDE_Knotify_Tutorial}}&lt;br /&gt;
&lt;br /&gt;
{{TutorialBrowser|&lt;br /&gt;
&lt;br /&gt;
series=Python|&lt;br /&gt;
&lt;br /&gt;
name=Python KNotify Tutorial|&lt;br /&gt;
&lt;br /&gt;
next=|&lt;br /&gt;
&lt;br /&gt;
reading=[http://techbase.kde.org/Development/Tutorials/Python_introduction_to_signals_and_slots Qt Signals and Slots in python], [http://www.learningpython.com/2008/09/20/an-introduction-to-pyqt/ Introduction to PyQT4], [http://techbase.kde.org/Development/Languages/Python/Using_PyKDE_4 Using PyKDE4]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Abstract ==&lt;br /&gt;
&lt;br /&gt;
The aim of this tutorial is to give a sample class to include Notifications and Jobs to your own python programms, so the user can see what is going on (for example a backup system, that tells you that is backuping right now). It assumes a basic working knowledge of Python and PyKDE4. &lt;br /&gt;
For now only the Job part is mentioned, 'cause that is the only part I've created right now.&lt;br /&gt;
&lt;br /&gt;
== Further plans ==&lt;br /&gt;
To add the Notification part also to this tutorial.&lt;br /&gt;
&lt;br /&gt;
== Instruction ==&lt;br /&gt;
&lt;br /&gt;
We start with a minimal KDE Appliciation ([http://techbase.kde.org/Development/Languages/Python/Using_PyKDE_4 Using PyKDE4]):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code python&amp;gt;&lt;br /&gt;
#! /usr/bin/python&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    import sys&lt;br /&gt;
    &lt;br /&gt;
    from PyKDE4.kdecore import KCmdLineArgs, KAboutData, KLocalizedString, ki18n&lt;br /&gt;
    from PyKDE4.kdeui import KApplication    &lt;br /&gt;
    &lt;br /&gt;
    appName     = &amp;quot;default&amp;quot;&lt;br /&gt;
    catalog     = &amp;quot;&amp;quot;&lt;br /&gt;
    programName = ki18n (&amp;quot;default&amp;quot;)  &lt;br /&gt;
    version     = &amp;quot;1.0&amp;quot;&lt;br /&gt;
    description = ki18n (&amp;quot;Default Example&amp;quot;)  &lt;br /&gt;
    license     = KAboutData.License_GPL&lt;br /&gt;
    copyright   = ki18n (&amp;quot;(c) 2010 Sandro Knauß&amp;quot;) &lt;br /&gt;
    text        = ki18n (&amp;quot;none&amp;quot;) &lt;br /&gt;
    homePage    = &amp;quot;techbase.kde.org&amp;quot;&lt;br /&gt;
    bugEmail    = &amp;quot;bugs@sandroknauss.de&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    aboutData   = KAboutData (appName, catalog, programName, version, description,&lt;br /&gt;
                              license, copyright, text, homePage, bugEmail)&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    KCmdLineArgs.init (sys.argv, aboutData)&lt;br /&gt;
    &lt;br /&gt;
    app = KApplication ()&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Job class ==&lt;br /&gt;
The first step is to have a look to the [http://api.kde.org]. The intersting on is:&lt;br /&gt;
* [http://api.kde.org/pykde-4.1-api/kdecore/KJob.html KJob(KDE 4.1-PyKDE4)]- unfortunately this documention is only available for KDE 4.1. So we have also a look to the actual C++ Doumentation&lt;br /&gt;
* [http://api.kde.org/4.x-api/kdelibs-apidocs/kdecore/html/classKJob.html KJob(KJob 4.x-C++API)]&lt;br /&gt;
&lt;br /&gt;
So it is easy to write a small Job-Class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code python&amp;gt;&lt;br /&gt;
from PyQt4.QtCore import QObject,QTimer,QString&lt;br /&gt;
from PyKDE4.kdecore import KJob&lt;br /&gt;
&lt;br /&gt;
class MyJob(KJob):&lt;br /&gt;
    def __init__(self,parent=QObject()):&lt;br /&gt;
        KJob.__init__(self,parent)&lt;br /&gt;
        #We want to have a Suspenable and Killable Job&lt;br /&gt;
        self.setCapabilities(KJob.Capabilities(KJob.Suspendable|KJob.Killable))&lt;br /&gt;
&lt;br /&gt;
        #Just a maximum Variable&lt;br /&gt;
        self.max=25&lt;br /&gt;
&lt;br /&gt;
        #index&lt;br /&gt;
        self.i=0&lt;br /&gt;
&lt;br /&gt;
    def start(self):&lt;br /&gt;
        #initalizing for work&lt;br /&gt;
        self.i=0&lt;br /&gt;
       &lt;br /&gt;
        #start the actual work in another thread&lt;br /&gt;
        #this function has to terminate, before the work is done&lt;br /&gt;
        QTimer().singleShot(0, self.doWork)&lt;br /&gt;
                                                                                                                                               &lt;br /&gt;
    def doWork(self):             &lt;br /&gt;
      #the actual work                                         &lt;br /&gt;
      try:            &lt;br /&gt;
            #if we are killed or suspended just return                                           &lt;br /&gt;
            if self.error() or self.isSuspended():                    &lt;br /&gt;
                return&lt;br /&gt;
        except RuntimeError:&lt;br /&gt;
            #if this class is killed before a RuntimeError will raise&lt;br /&gt;
            return&lt;br /&gt;
&lt;br /&gt;
        #do a peace of hard work&lt;br /&gt;
        self.i+=1&lt;br /&gt;
&lt;br /&gt;
        #fortunately we have made a peace of work &lt;br /&gt;
        #-&amp;gt; show this to everybody&lt;br /&gt;
        KJob.setPercent(self,self.i*4)&lt;br /&gt;
       &lt;br /&gt;
        if self.i==self.max:&lt;br /&gt;
            #jeah we have done the bunch of work&lt;br /&gt;
            #send the result signal for showing, that we ended the work&lt;br /&gt;
            self.emitResult()&lt;br /&gt;
            return &lt;br /&gt;
        #just go to sleep for 1000ms than go on&lt;br /&gt;
        QTimer().singleShot(1000, self.doWork)&lt;br /&gt;
    &lt;br /&gt;
    def doSuspend(self):&lt;br /&gt;
        #the surounding function from KJob makes the isSuspended() become True&lt;br /&gt;
        #returns True for signaling that this class supports to suspend&lt;br /&gt;
        return True&lt;br /&gt;
&lt;br /&gt;
    def doResume(self):&lt;br /&gt;
        #start with work again&lt;br /&gt;
        QTimer().singleShot( 0, self.doWork )&lt;br /&gt;
        #return True for signaling that this class supports resuming&lt;br /&gt;
        return True&lt;br /&gt;
&lt;br /&gt;
    def doKill(self):&lt;br /&gt;
        #return True for signaling that we support killing&lt;br /&gt;
        return True&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===What is going on?===&lt;br /&gt;
* '''MyJob.__init__''': First we create the class and initialize the counter ''i'' and the maximum ''max''. To make is visible for others we set the Capacities, so this job is suspendable and killable.&lt;br /&gt;
* '''MyJob.start''': Here the pre working setting are made, we will se later for what we use this. After initalizing the Work we start the actual work by using a QTimer. The start method should start the asyncron.&lt;br /&gt;
* '''MyJob.doWork''': Do actual work and handle, if this job is killed or suspended.&lt;br /&gt;
* '''MyJob.doSuspend'''/'''MyJob.doResume'''/'''MyJob.doKill''': These function indicate that this feature is supported by this class.&lt;br /&gt;
&lt;br /&gt;
===How to use?===&lt;br /&gt;
Just create a instance of this class and start it:&lt;br /&gt;
&amp;lt;code python&amp;gt;&lt;br /&gt;
job=MyJob(app)&lt;br /&gt;
job.start()&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===We want to know when the jobs done?===&lt;br /&gt;
Create a '''SLOT''' to the '''result'''-signal:&lt;br /&gt;
&amp;lt;code python&amp;gt;&lt;br /&gt;
def handleResult(job):&lt;br /&gt;
    #handleResult Function&lt;br /&gt;
    #it is called when the job is terminating&lt;br /&gt;
    if job.error():&lt;br /&gt;
       print 'error happend'&lt;br /&gt;
    else:&lt;br /&gt;
       print 'job has terminated successfully'&lt;br /&gt;
&lt;br /&gt;
job.result.connect(handleResult)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Visual feedback===&lt;br /&gt;
Till now, a normal user doesn't see anything what is going on. To change it we have to register the Job to a JobTracker.  Now a user will see a progressbar and a suspend and a stop button. So we modify the start method:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code python&amp;gt;&lt;br /&gt;
from PyKDE4.kio import KIO&lt;br /&gt;
...&lt;br /&gt;
    def start(self):&lt;br /&gt;
        #register the Job to the JobTracker&lt;br /&gt;
        KIO.getJobTracker().registerJob(self)&lt;br /&gt;
        self.i=0&lt;br /&gt;
        QTimer().singleShot(0, self.doWork)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Conclusion ===&lt;br /&gt;
Here is the [[Development/Languages/Python/PyKDE_Knotify_Tutorial/MyJob.py|full code]] of this example. &lt;br /&gt;
&lt;br /&gt;
Is is very easy to create a Job and make it visible to normal users. Unfortunately I have problems with setting the heading and description, so this will be added in later versions.&lt;/div&gt;</summary>
		<author><name>Hefee</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Languages/Python/PyKDE_Knotify_Tutorial</id>
		<title>Development/Languages/Python/PyKDE Knotify Tutorial</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Languages/Python/PyKDE_Knotify_Tutorial"/>
				<updated>2010-08-09T23:18:46Z</updated>
		
		<summary type="html">&lt;p&gt;Hefee: whats going on?&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:I18n/Language Navigation Bar|Development/Languages/Python/PyKDE_Knotify_Tutorial}}&lt;br /&gt;
&lt;br /&gt;
{{TutorialBrowser|&lt;br /&gt;
&lt;br /&gt;
series=Python|&lt;br /&gt;
&lt;br /&gt;
name=Python KNotify Tutorial|&lt;br /&gt;
&lt;br /&gt;
next=|&lt;br /&gt;
&lt;br /&gt;
reading=[http://techbase.kde.org/Development/Tutorials/Python_introduction_to_signals_and_slots Qt Signals and Slots in python], [http://www.learningpython.com/2008/09/20/an-introduction-to-pyqt/ Introduction to PyQT4], [http://techbase.kde.org/Development/Languages/Python/Using_PyKDE_4 Using PyKDE4]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Abstract ==&lt;br /&gt;
&lt;br /&gt;
The aim of this tutorial is to give a sample class to include Notifications and Jobs to your own python programms, so the user can see what is going on (for example a backup system, that tells you that is backuping right now). It assumes a basic working knowledge of Python and PyKDE4. &lt;br /&gt;
For now only the Job part is mentioned, 'cause that is the only part I've created right now.&lt;br /&gt;
&lt;br /&gt;
== Further plans ==&lt;br /&gt;
To add the Notification part also to this tutorial.&lt;br /&gt;
&lt;br /&gt;
== Instruction ==&lt;br /&gt;
&lt;br /&gt;
We start with a minimal KDE Appliciation ([http://techbase.kde.org/Development/Languages/Python/Using_PyKDE_4 Using PyKDE4]):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code python&amp;gt;&lt;br /&gt;
#! /usr/bin/python&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    import sys&lt;br /&gt;
    &lt;br /&gt;
    from PyKDE4.kdecore import KCmdLineArgs, KAboutData, KLocalizedString, ki18n&lt;br /&gt;
    from PyKDE4.kdeui import KApplication    &lt;br /&gt;
    &lt;br /&gt;
    appName     = &amp;quot;default&amp;quot;&lt;br /&gt;
    catalog     = &amp;quot;&amp;quot;&lt;br /&gt;
    programName = ki18n (&amp;quot;default&amp;quot;)  &lt;br /&gt;
    version     = &amp;quot;1.0&amp;quot;&lt;br /&gt;
    description = ki18n (&amp;quot;Default Example&amp;quot;)  &lt;br /&gt;
    license     = KAboutData.License_GPL&lt;br /&gt;
    copyright   = ki18n (&amp;quot;(c) 2010 Sandro Knauß&amp;quot;) &lt;br /&gt;
    text        = ki18n (&amp;quot;none&amp;quot;) &lt;br /&gt;
    homePage    = &amp;quot;techbase.kde.org&amp;quot;&lt;br /&gt;
    bugEmail    = &amp;quot;bugs@sandroknauss.de&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    aboutData   = KAboutData (appName, catalog, programName, version, description,&lt;br /&gt;
                              license, copyright, text, homePage, bugEmail)&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    KCmdLineArgs.init (sys.argv, aboutData)&lt;br /&gt;
    &lt;br /&gt;
    app = KApplication ()&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Job class ==&lt;br /&gt;
The first step is to have a look to the [http://api.kde.org]. The intersting on is:&lt;br /&gt;
* [http://api.kde.org/pykde-4.1-api/kdecore/KJob.html KJob(KDE 4.1-PyKDE4)]- unfortunately this documention is only available for KDE 4.1. So we have also a look to the actual C++ Doumentation&lt;br /&gt;
* [http://api.kde.org/4.x-api/kdelibs-apidocs/kdecore/html/classKJob.html KJob(KJob 4.x-C++API)]&lt;br /&gt;
&lt;br /&gt;
So it is easy to write a small Job-Class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code python&amp;gt;&lt;br /&gt;
from PyQt4.QtCore import QObject,QTimer,QString&lt;br /&gt;
from PyKDE4.kdecore import KJob&lt;br /&gt;
&lt;br /&gt;
class MyJob(KJob):&lt;br /&gt;
    def __init__(self,parent=QObject()):&lt;br /&gt;
        KJob.__init__(self,parent)&lt;br /&gt;
        #We want to have a Suspenable and Killable Job&lt;br /&gt;
        self.setCapabilities(KJob.Capabilities(KJob.Suspendable|KJob.Killable))&lt;br /&gt;
&lt;br /&gt;
        #Just a maximum Variable&lt;br /&gt;
        self.max=25&lt;br /&gt;
&lt;br /&gt;
        #index&lt;br /&gt;
        self.i=0&lt;br /&gt;
&lt;br /&gt;
    def start(self):&lt;br /&gt;
        #initalizing for work&lt;br /&gt;
        self.i=0&lt;br /&gt;
       &lt;br /&gt;
        #start the actual work in another thread&lt;br /&gt;
        #this function has to terminate, before the work is done&lt;br /&gt;
        QTimer().singleShot( 0, self.doWork )&lt;br /&gt;
                                                                                                                                               &lt;br /&gt;
    def doWork(self):             &lt;br /&gt;
      #the actual work                                         &lt;br /&gt;
      try:            &lt;br /&gt;
            #if we are killed or suspended just return                                           &lt;br /&gt;
            if self.error() or self.isSuspended():                    &lt;br /&gt;
                return&lt;br /&gt;
        except RuntimeError:&lt;br /&gt;
            #if this class is killed before a RuntimeError will raise&lt;br /&gt;
            return&lt;br /&gt;
&lt;br /&gt;
        #do a peace of hard work&lt;br /&gt;
        self.i+=1&lt;br /&gt;
&lt;br /&gt;
        #fortunately we have made a peace of work &lt;br /&gt;
        #-&amp;gt; show this to everybody&lt;br /&gt;
        KJob.setPercent(self,self.i*4)&lt;br /&gt;
       &lt;br /&gt;
        if self.i==self.max:&lt;br /&gt;
            #jeah we have done the bunch of work&lt;br /&gt;
            #send the result signal for showing, that we ended the work&lt;br /&gt;
            self.emitResult()&lt;br /&gt;
            return &lt;br /&gt;
        #just go to sleep for 1000ms than go on&lt;br /&gt;
        QTimer().singleShot( 1000, self.doWork )&lt;br /&gt;
    &lt;br /&gt;
    def doSuspend(self):&lt;br /&gt;
        #the surounding function from KJob makes the isSuspended() become True&lt;br /&gt;
        #returns True for signaling that this class supports to suspend&lt;br /&gt;
        return True&lt;br /&gt;
&lt;br /&gt;
    def doResume(self):&lt;br /&gt;
        #start with work again&lt;br /&gt;
        QTimer().singleShot( 0, self.doWork )&lt;br /&gt;
        #return True for signaling that this class supports resuming&lt;br /&gt;
        return True&lt;br /&gt;
&lt;br /&gt;
    def doKill(self):&lt;br /&gt;
        #return True for signaling that we support killing&lt;br /&gt;
        return True&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===What is going on?===&lt;br /&gt;
* '''MyJob.__init__''': First we create the class and initialize the counter ''i'' and the maximum ''max''. To make is visible for others we set the Capacities, so this job is suspendable and killable.&lt;br /&gt;
* '''MyJob.start''': Here the pre working setting are made, we will se later for what we use this. After initalizing the Work we start the actual work by using a QTimer. The start method should start the asyncron.&lt;br /&gt;
* '''MyJob.doWork''': Do actual work and handle, if this job is killed or suspended.&lt;br /&gt;
* '''MyJob.doSuspend'''/'''MyJob.doResume'''/'''MyJob.doKill''': These function indicate that this feature is supported by this class.&lt;/div&gt;</summary>
		<author><name>Hefee</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Languages/Python/PyKDE_Knotify_Tutorial</id>
		<title>Development/Languages/Python/PyKDE Knotify Tutorial</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Languages/Python/PyKDE_Knotify_Tutorial"/>
				<updated>2010-08-09T23:06:01Z</updated>
		
		<summary type="html">&lt;p&gt;Hefee: i18n tamplate&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:I18n/Language Navigation Bar|Development/Languages/Python/PyKDE_Knotify_Tutorial}}&lt;br /&gt;
&lt;br /&gt;
{{TutorialBrowser|&lt;br /&gt;
&lt;br /&gt;
series=Python|&lt;br /&gt;
&lt;br /&gt;
name=Python KNotify Tutorial|&lt;br /&gt;
&lt;br /&gt;
next=|&lt;br /&gt;
&lt;br /&gt;
reading=[http://techbase.kde.org/Development/Tutorials/Python_introduction_to_signals_and_slots Qt Signals and Slots in python], [http://www.learningpython.com/2008/09/20/an-introduction-to-pyqt/ Introduction to PyQT4], [http://techbase.kde.org/Development/Languages/Python/Using_PyKDE_4 Using PyKDE4]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Abstract ==&lt;br /&gt;
&lt;br /&gt;
The aim of this tutorial is to give a sample class to include Notifications and Jobs to your own python programms, so the user can see what is going on (for example a backup system, that tells you that is backuping right now). It assumes a basic working knowledge of Python and PyKDE4. &lt;br /&gt;
For now only the Job part is mentioned, 'cause that is the only part I've created right now.&lt;br /&gt;
&lt;br /&gt;
== Further plans ==&lt;br /&gt;
To add the Notification part also to this tutorial.&lt;br /&gt;
&lt;br /&gt;
== Instruction ==&lt;br /&gt;
&lt;br /&gt;
We start with a minimal KDE Appliciation ([http://techbase.kde.org/Development/Languages/Python/Using_PyKDE_4 Using PyKDE4]):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code python&amp;gt;&lt;br /&gt;
#! /usr/bin/python&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    import sys&lt;br /&gt;
    &lt;br /&gt;
    from PyKDE4.kdecore import KCmdLineArgs, KAboutData, KLocalizedString, ki18n&lt;br /&gt;
    from PyKDE4.kdeui import KApplication    &lt;br /&gt;
    &lt;br /&gt;
    appName     = &amp;quot;default&amp;quot;&lt;br /&gt;
    catalog     = &amp;quot;&amp;quot;&lt;br /&gt;
    programName = ki18n (&amp;quot;default&amp;quot;)  &lt;br /&gt;
    version     = &amp;quot;1.0&amp;quot;&lt;br /&gt;
    description = ki18n (&amp;quot;Default Example&amp;quot;)  &lt;br /&gt;
    license     = KAboutData.License_GPL&lt;br /&gt;
    copyright   = ki18n (&amp;quot;(c) 2010 Sandro Knauß&amp;quot;) &lt;br /&gt;
    text        = ki18n (&amp;quot;none&amp;quot;) &lt;br /&gt;
    homePage    = &amp;quot;techbase.kde.org&amp;quot;&lt;br /&gt;
    bugEmail    = &amp;quot;bugs@sandroknauss.de&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    aboutData   = KAboutData (appName, catalog, programName, version, description,&lt;br /&gt;
                              license, copyright, text, homePage, bugEmail)&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    KCmdLineArgs.init (sys.argv, aboutData)&lt;br /&gt;
    &lt;br /&gt;
    app = KApplication ()&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Job class ==&lt;br /&gt;
The first step is to have a look to the [http://api.kde.org]. The intersting on is:&lt;br /&gt;
* [http://api.kde.org/pykde-4.1-api/kdecore/KJob.html KJob(KDE 4.1-PyKDE4)]- unfortunately this documention is only available for KDE 4.1. So we have also a look to the actual C++ Doumentation&lt;br /&gt;
* [http://api.kde.org/4.x-api/kdelibs-apidocs/kdecore/html/classKJob.html KJob(KJob 4.x-C++API)]&lt;br /&gt;
&lt;br /&gt;
So it is easy to write a small Job-Class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code python&amp;gt;&lt;br /&gt;
from PyQt4.QtCore import QObject,QTimer,QString&lt;br /&gt;
from PyKDE4.kdecore import KJob&lt;br /&gt;
&lt;br /&gt;
class MyJob(KJob):&lt;br /&gt;
    def __init__(self,parent=QObject()):&lt;br /&gt;
        KJob.__init__(self,parent)&lt;br /&gt;
        #We want to have a Suspenable and Killable Job&lt;br /&gt;
        self.setCapabilities(KJob.Capabilities(KJob.Suspendable|KJob.Killable))&lt;br /&gt;
&lt;br /&gt;
        #Just a maximum Variable&lt;br /&gt;
        self.max=25&lt;br /&gt;
&lt;br /&gt;
        #index&lt;br /&gt;
        self.i=0&lt;br /&gt;
&lt;br /&gt;
    def start(self):&lt;br /&gt;
        #initalizing for work&lt;br /&gt;
        self.i=0&lt;br /&gt;
       &lt;br /&gt;
        #start the actual work in another thread - this function has to terminate, before the work is done&lt;br /&gt;
        QTimer().singleShot( 0, self.doWork )&lt;br /&gt;
                                                                                                                                               &lt;br /&gt;
    def doWork(self):             &lt;br /&gt;
      #the actual work                                         &lt;br /&gt;
      try:            &lt;br /&gt;
            #if we are killed or suspended just return                                           &lt;br /&gt;
            if self.error() or self.isSuspended():                    &lt;br /&gt;
                return&lt;br /&gt;
        except RuntimeError:&lt;br /&gt;
            #if this class is killed before this functions is called a RuntimeError will raise&lt;br /&gt;
            return&lt;br /&gt;
&lt;br /&gt;
        #do a peace of hard work&lt;br /&gt;
        self.i+=1&lt;br /&gt;
&lt;br /&gt;
        #fortunately we have made a peace of work -&amp;gt; show this to everybody&lt;br /&gt;
        KJob.setPercent(self,self.i*4)&lt;br /&gt;
       &lt;br /&gt;
        if self.i==self.max:&lt;br /&gt;
            #jeah we have done the bunch of work&lt;br /&gt;
            #send the result signal for showing, that we ended the work&lt;br /&gt;
            self.emitResult()&lt;br /&gt;
            return &lt;br /&gt;
        #just go to sleep for 1000ms than go on&lt;br /&gt;
        QTimer().singleShot( 1000, self.doWork )&lt;br /&gt;
    &lt;br /&gt;
    def doSuspend(self):&lt;br /&gt;
        #the surounding function from KJob makes the isSuspended() become True&lt;br /&gt;
        #returns True for signaling that this class supports to suspend&lt;br /&gt;
        return True&lt;br /&gt;
&lt;br /&gt;
    def doResume(self):&lt;br /&gt;
        #start with work again&lt;br /&gt;
        QTimer().singleShot( 0, self.doWork )&lt;br /&gt;
        #return True for signaling that this class supports resuming&lt;br /&gt;
        return True&lt;br /&gt;
&lt;br /&gt;
    def doKill(self):&lt;br /&gt;
        #return True for signaling that we support killing&lt;br /&gt;
        return True&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Hefee</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Languages/Python/PyKDE_Knotify_Tutorial</id>
		<title>Development/Languages/Python/PyKDE Knotify Tutorial</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Languages/Python/PyKDE_Knotify_Tutorial"/>
				<updated>2010-08-09T23:01:37Z</updated>
		
		<summary type="html">&lt;p&gt;Hefee: KJob class&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:I18n/Language Navigation Bar|Development/Tutorials/Python/PyKDE_KNotify_Tutorial}}&lt;br /&gt;
&lt;br /&gt;
{{TutorialBrowser|&lt;br /&gt;
&lt;br /&gt;
series=Python|&lt;br /&gt;
&lt;br /&gt;
name=Python KNotify Tutorial|&lt;br /&gt;
&lt;br /&gt;
next=|&lt;br /&gt;
&lt;br /&gt;
reading=[http://techbase.kde.org/Development/Tutorials/Python_introduction_to_signals_and_slots Qt Signals and Slots in python], [http://www.learningpython.com/2008/09/20/an-introduction-to-pyqt/ Introduction to PyQT4], [http://techbase.kde.org/Development/Languages/Python/Using_PyKDE_4 Using PyKDE4]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Abstract ==&lt;br /&gt;
&lt;br /&gt;
The aim of this tutorial is to give a sample class to include Notifications and Jobs to your own python programms, so the user can see what is going on (for example a backup system, that tells you that is backuping right now). It assumes a basic working knowledge of Python and PyKDE4. &lt;br /&gt;
For now only the Job part is mentioned, 'cause that is the only part I've created right now.&lt;br /&gt;
&lt;br /&gt;
== Further plans ==&lt;br /&gt;
To add the Notification part also to this tutorial.&lt;br /&gt;
&lt;br /&gt;
== Instruction ==&lt;br /&gt;
&lt;br /&gt;
We start with a minimal KDE Appliciation ([http://techbase.kde.org/Development/Languages/Python/Using_PyKDE_4 Using PyKDE4]):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code python&amp;gt;&lt;br /&gt;
#! /usr/bin/python&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    import sys&lt;br /&gt;
    &lt;br /&gt;
    from PyKDE4.kdecore import KCmdLineArgs, KAboutData, KLocalizedString, ki18n&lt;br /&gt;
    from PyKDE4.kdeui import KApplication    &lt;br /&gt;
    &lt;br /&gt;
    appName     = &amp;quot;default&amp;quot;&lt;br /&gt;
    catalog     = &amp;quot;&amp;quot;&lt;br /&gt;
    programName = ki18n (&amp;quot;default&amp;quot;)  &lt;br /&gt;
    version     = &amp;quot;1.0&amp;quot;&lt;br /&gt;
    description = ki18n (&amp;quot;Default Example&amp;quot;)  &lt;br /&gt;
    license     = KAboutData.License_GPL&lt;br /&gt;
    copyright   = ki18n (&amp;quot;(c) 2010 Sandro Knauß&amp;quot;) &lt;br /&gt;
    text        = ki18n (&amp;quot;none&amp;quot;) &lt;br /&gt;
    homePage    = &amp;quot;techbase.kde.org&amp;quot;&lt;br /&gt;
    bugEmail    = &amp;quot;bugs@sandroknauss.de&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    aboutData   = KAboutData (appName, catalog, programName, version, description,&lt;br /&gt;
                              license, copyright, text, homePage, bugEmail)&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    KCmdLineArgs.init (sys.argv, aboutData)&lt;br /&gt;
    &lt;br /&gt;
    app = KApplication ()&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Job class ==&lt;br /&gt;
The first step is to have a look to the [http://api.kde.org]. The intersting on is:&lt;br /&gt;
* [http://api.kde.org/pykde-4.1-api/kdecore/KJob.html KJob(KDE 4.1-PyKDE4)]- unfortunately this documention is only available for KDE 4.1. So we have also a look to the actual C++ Doumentation&lt;br /&gt;
* [http://api.kde.org/4.x-api/kdelibs-apidocs/kdecore/html/classKJob.html KJob(KJob 4.x-C++API)]&lt;br /&gt;
&lt;br /&gt;
So it is easy to write a small Job-Class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code python&amp;gt;&lt;br /&gt;
from PyQt4.QtCore import QObject,QTimer,QString&lt;br /&gt;
from PyKDE4.kdecore import KJob&lt;br /&gt;
&lt;br /&gt;
class MyJob(KJob):&lt;br /&gt;
    def __init__(self,parent=QObject()):&lt;br /&gt;
        KJob.__init__(self,parent)&lt;br /&gt;
        #We want to have a Suspenable and Killable Job&lt;br /&gt;
        self.setCapabilities(KJob.Capabilities(KJob.Suspendable|KJob.Killable))&lt;br /&gt;
&lt;br /&gt;
        #Just a maximum Variable&lt;br /&gt;
        self.max=25&lt;br /&gt;
&lt;br /&gt;
        #index&lt;br /&gt;
        self.i=0&lt;br /&gt;
&lt;br /&gt;
    def start(self):&lt;br /&gt;
        #initalizing for work&lt;br /&gt;
        self.i=0&lt;br /&gt;
       &lt;br /&gt;
        #start the actual work in another thread - this function has to terminate, before the work is done&lt;br /&gt;
        QTimer().singleShot( 0, self.doWork )&lt;br /&gt;
                                                                                                                                               &lt;br /&gt;
    def doWork(self):             &lt;br /&gt;
      #the actual work                                         &lt;br /&gt;
      try:            &lt;br /&gt;
            #if we are killed or suspended just return                                           &lt;br /&gt;
            if self.error() or self.isSuspended():                    &lt;br /&gt;
                return&lt;br /&gt;
        except RuntimeError:&lt;br /&gt;
            #if this class is killed before this functions is called a RuntimeError will raise&lt;br /&gt;
            return&lt;br /&gt;
&lt;br /&gt;
        #do a peace of hard work&lt;br /&gt;
        self.i+=1&lt;br /&gt;
&lt;br /&gt;
        #fortunately we have made a peace of work -&amp;gt; show this to everybody&lt;br /&gt;
        KJob.setPercent(self,self.i*4)&lt;br /&gt;
       &lt;br /&gt;
        if self.i==self.max:&lt;br /&gt;
            #jeah we have done the bunch of work&lt;br /&gt;
            #send the result signal for showing, that we ended the work&lt;br /&gt;
            self.emitResult()&lt;br /&gt;
            return &lt;br /&gt;
        #just go to sleep for 1000ms than go on&lt;br /&gt;
        QTimer().singleShot( 1000, self.doWork )&lt;br /&gt;
    &lt;br /&gt;
    def doSuspend(self):&lt;br /&gt;
        #the surounding function from KJob makes the isSuspended() become True&lt;br /&gt;
        #returns True for signaling that this class supports to suspend&lt;br /&gt;
        return True&lt;br /&gt;
&lt;br /&gt;
    def doResume(self):&lt;br /&gt;
        #start with work again&lt;br /&gt;
        QTimer().singleShot( 0, self.doWork )&lt;br /&gt;
        #return True for signaling that this class supports resuming&lt;br /&gt;
        return True&lt;br /&gt;
&lt;br /&gt;
    def doKill(self):&lt;br /&gt;
        #return True for signaling that we support killing&lt;br /&gt;
        return True&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Hefee</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Languages/Python</id>
		<title>Development/Languages/Python</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Languages/Python"/>
				<updated>2010-08-09T22:39:13Z</updated>
		
		<summary type="html">&lt;p&gt;Hefee: /* Documentation and Tutorials */  KNotify&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:I18n/Language Navigation Bar|Development/Languages/Python}}&lt;br /&gt;
&lt;br /&gt;
Python is a powerful object oriented, dynamic language. You can find out more about the language itself on the Python website at http://www.python.org/.&lt;br /&gt;
&lt;br /&gt;
Two important pieces of software are needed to develop KDE applications using Python, [http://www.riverbankcomputing.co.uk/software/pyqt/intro PyQt] and PyKDE. PyQt provides Python support for the Qt library which KDE is built on. PyQt can be obtained at http://www.riverbankcomputing.co.uk/software/pyqt/ . Riverbank Computing has a lot of good documentation about how to use PyQt to create pure Qt applications. If you are new to KDE / Python development, then learning how to use PyQt is the best first step.&lt;br /&gt;
&lt;br /&gt;
PyKDE builds on top of PyQt and adds Python support for KDE's libraries and technologies.&lt;br /&gt;
&lt;br /&gt;
PyKDE is distributed as part of the kdebindings module. Stable releases can be downloaded from the normal [http://kde.org/download/ KDE download page], although it is usually easier to install pre-built packages from your operating system distribution. You can also obtain PyKDE from KDE's subversion repository:&lt;br /&gt;
&lt;br /&gt;
 svn co svn://anonsvn.kde.org/home/kde/trunk/KDE/kdebindings/python/pykde4&lt;br /&gt;
&lt;br /&gt;
The code in subversion can be browsed online via http://websvn.kde.org/trunk/KDE/kdebindings/python/pykde4/.&lt;br /&gt;
&lt;br /&gt;
==Documentation and Tutorials==&lt;br /&gt;
* [http://www.riverbankcomputing.co.uk/software/pyqt/intro PyQt home page and documentation]&lt;br /&gt;
* [[/Using PyKDE 4|Using PyKDE 4]]&lt;br /&gt;
* [http://api.kde.org/pykde-4.3-api/toc.html PyKDE 4.3 Documentation]&lt;br /&gt;
* [http://api.kde.org/pykde-4.3-api/modules.html PyKDE 4.3 API class reference]&lt;br /&gt;
* [http://api.kde.org/pykde-4.2-api/ PyKDE 4.2 API class reference]&lt;br /&gt;
* [[/PyKDE_WebKit_Tutorial|PyKDE WebKit Tutorial]], a simple web browser application in PyKDE&lt;br /&gt;
* [[Development/Tutorials/Python introduction to signals and slots|introduction to signals and slots]]&lt;br /&gt;
* [http://www.rkblog.rk.edu.pl/w/p/introduction-pyqt4/ Introduction article about PyQt4]&lt;br /&gt;
* [http://lateral.netmanagers.com.ar/stories/BBS47.html PyQt by Example]&lt;br /&gt;
* [[/PyKDE_DBus_Tutorial|Python DBus Tutorial]]. See how to call dbus methods from PyKDE.&lt;br /&gt;
* [[/PyKDE_Knotify_Tutorial|Python KNotify Tutorial]]. How to use Notification and Jobs in your Applications&lt;br /&gt;
* [[Development/Tutorials/Phonon/Introduction/Python|Phonon Example]]&lt;br /&gt;
* [[Development/Tutorials/Plasma#Plasma_Programming_with_Python|Plasma tutorials]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===KDE 3 and PyKDE 3===&lt;br /&gt;
Documentation and tutorials for the older PyQt and PyKDE 3.&lt;br /&gt;
* [http://vizzzion.org/?id=pyqt Python-Qt tutorial]&amp;lt;br /&amp;gt;''&amp;lt;font size=&amp;quot;-1&amp;quot;&amp;gt; In this tutorial, the basic steps of creating a Qt-based application with PyQt are explained. &amp;lt;/font&amp;gt;''&lt;br /&gt;
&lt;br /&gt;
==Further reading and information==&lt;br /&gt;
*[http://www.riverbankcomputing.com/mailman/listinfo/pyqt PyQt and PyKDE mailing list]&lt;br /&gt;
*[http://www.riverbankcomputing.co.uk/software/pykde/intro PyKDE Homepage]&lt;br /&gt;
*[http://www.diotavelli.net/PyQtWiki The PyQt and PyKDE community Wiki]&lt;br /&gt;
*The book [http://www.qtrac.eu/pyqtbook.html Rapid GUI Programming with Python and Qt] is available and covers Qt 4 programming with Python.&lt;br /&gt;
*The IRC channel ''#kubuntu-devel'' on freenode often has PyKDE programmers in it.&lt;br /&gt;
*The IRC channel ''#pyqt'' on freenode is used by some PyQt application developers.&lt;br /&gt;
&lt;br /&gt;
==Applications using PyKDE==&lt;br /&gt;
*[http://utils.kde.org/projects/printer-applet/ printer-applet]&lt;br /&gt;
*[http://websvn.kde.org/trunk/KDE/kdeadmin/system-config-printer-kde/ system-config-printer-kde]&lt;br /&gt;
*[http://websvn.kde.org/trunk/extragear/utils/guidance-power-manager/ Guidance Power Manager], a battery applet&lt;br /&gt;
*[https://code.launchpad.net/ubiquity/trunk Ubiquity], installer for Kubuntu&lt;br /&gt;
*[https://code.launchpad.net/~ubuntu-core-dev/gdebi/ubuntu GDebi], .deb package installer&lt;br /&gt;
*[https://code.launchpad.net/~jr/install-package/trunk install-package], graphical apt-get&lt;br /&gt;
*[http://draketo.de/light/english/pyrad pyRad], wheel type command interface&lt;br /&gt;
*[http://websvn.kde.org/trunk/KDE/kdebindings/python/pykde4/examples/ some examples are in the PyKDE source]&lt;br /&gt;
&lt;br /&gt;
[[Category:Python]]&lt;/div&gt;</summary>
		<author><name>Hefee</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Languages/Python/PyKDE_Knotify_Tutorial</id>
		<title>Development/Languages/Python/PyKDE Knotify Tutorial</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Languages/Python/PyKDE_Knotify_Tutorial"/>
				<updated>2010-08-09T22:37:10Z</updated>
		
		<summary type="html">&lt;p&gt;Hefee: minimal kde application&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:I18n/Language Navigation Bar|Development/Tutorials/Python/PyKDE_KNotify_Tutorial}}&lt;br /&gt;
&lt;br /&gt;
{{TutorialBrowser|&lt;br /&gt;
&lt;br /&gt;
series=Python|&lt;br /&gt;
&lt;br /&gt;
name=Python KNotify Tutorial|&lt;br /&gt;
&lt;br /&gt;
next=|&lt;br /&gt;
&lt;br /&gt;
reading=[http://techbase.kde.org/Development/Tutorials/Python_introduction_to_signals_and_slots Qt Signals and Slots in python], [http://www.learningpython.com/2008/09/20/an-introduction-to-pyqt/ Introduction to PyQT4], [http://techbase.kde.org/Development/Languages/Python/Using_PyKDE_4 Using PyKDE4]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Abstract ==&lt;br /&gt;
&lt;br /&gt;
The aim of this tutorial is to give a sample class to include Notifications and Jobs to your own python programms, so the user can see what is going on (for example a backup system, that tells you that is backuping right now). It assumes a basic working knowledge of Python and PyKDE4. &lt;br /&gt;
For now only the Job part is mentioned, 'cause that is the only part I've created right now.&lt;br /&gt;
&lt;br /&gt;
== Further plans ==&lt;br /&gt;
To add the Notification part also to this tutorial.&lt;br /&gt;
&lt;br /&gt;
== Instruction ==&lt;br /&gt;
&lt;br /&gt;
We start with a minimal KDE Appliciation ([http://techbase.kde.org/Development/Languages/Python/Using_PyKDE_4 Using PyKDE4]):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code python&amp;gt;&lt;br /&gt;
#! /usr/bin/python&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    import sys&lt;br /&gt;
    &lt;br /&gt;
    from PyKDE4.kdecore import KCmdLineArgs, KAboutData, KLocalizedString, ki18n&lt;br /&gt;
    from PyKDE4.kdeui import KApplication    &lt;br /&gt;
    &lt;br /&gt;
    appName     = &amp;quot;default&amp;quot;&lt;br /&gt;
    catalog     = &amp;quot;&amp;quot;&lt;br /&gt;
    programName = ki18n (&amp;quot;default&amp;quot;)  &lt;br /&gt;
    version     = &amp;quot;1.0&amp;quot;&lt;br /&gt;
    description = ki18n (&amp;quot;Default Example&amp;quot;)  &lt;br /&gt;
    license     = KAboutData.License_GPL&lt;br /&gt;
    copyright   = ki18n (&amp;quot;(c) 2010 Sandro Knauß&amp;quot;) &lt;br /&gt;
    text        = ki18n (&amp;quot;none&amp;quot;) &lt;br /&gt;
    homePage    = &amp;quot;techbase.kde.org&amp;quot;&lt;br /&gt;
    bugEmail    = &amp;quot;bugs@sandroknauss.de&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    aboutData   = KAboutData (appName, catalog, programName, version, description,&lt;br /&gt;
                              license, copyright, text, homePage, bugEmail)&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    KCmdLineArgs.init (sys.argv, aboutData)&lt;br /&gt;
    &lt;br /&gt;
    app = KApplication ()&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Hefee</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials</id>
		<title>Development/Tutorials</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials"/>
				<updated>2010-08-09T22:15:43Z</updated>
		
		<summary type="html">&lt;p&gt;Hefee: /* Python */  KNotify&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:I18n/Language Navigation Bar|Development/Tutorials}}&lt;br /&gt;
&lt;br /&gt;
Tutorials are the fastest way of finding out what KDE will do for you, and how to do it. Here is a list of currently available tutorials '''for KDE4'''. Material for KDE3 and KDE2 is available on the bottom of this page.&lt;br /&gt;
&lt;br /&gt;
== Introduction To KDE 4 Programming ==&lt;br /&gt;
Are you interested in writing applications with KDE 4? This tutorial series is aimed at those completely new to KDE programming.&lt;br /&gt;
;[[Development/Tutorials/First program|Hello World]]&lt;br /&gt;
:''A preliminary introduction to the very basics of KDE4 programming''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Using KXmlGuiWindow|Creating the Main Window]]&lt;br /&gt;
:''This tutorial shows you the magic of an application's most important thing: The main window.''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Using KActions|Using KActions]]&lt;br /&gt;
:''How to add actions to the menus and toolbars.''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Saving and loading|Saving and Loading]]&lt;br /&gt;
:''Introduces the KIO library while adding loading and saving support to our application.''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/KCmdLineArgs|Command line arguments]]&lt;br /&gt;
:''Adds the ability to specify which file to open from the command line to our text editor.''&lt;br /&gt;
&lt;br /&gt;
== Basics ==&lt;br /&gt;
;[[Development/Tutorials/KDE4 Porting Guide|Porting Your Application]]&lt;br /&gt;
:''Help Porting Applications from Qt3/KDE3 to Qt4/KDE4''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/CMake|Introduction to CMake]]&lt;br /&gt;
:''How to use the CMake build system used by KDE4.''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Common Programming Mistakes|Common Programming Mistakes]]&lt;br /&gt;
:''Various common mistakes made while developing Qt and KDE applications and how to avoid them.''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Using Qt Designer|Using Qt Designer to build user interfaces]]&lt;br /&gt;
:''How to create UI files with designer, and how to integrate them into a KDE program.''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Using Qt Creator|Using Qt Creator to develop your KDE program]]&lt;br /&gt;
:''How to integrate Qt Creator use into KDE development.''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Creating Libraries|Creating Libraries to share code]]&lt;br /&gt;
:''How to add the library to the buildsystem and how to prepare the source code.''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Session_Management|Session Management]]&lt;br /&gt;
:''Make your application aware of X sessions''&lt;br /&gt;
&lt;br /&gt;
== Testing And Debugging ==&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Debugging|Debugging your application]]&lt;br /&gt;
:''Tips, tools and techniques to apply when debugging your KDE application''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Unittests|Writing Unittests for Qt4 and KDE4 with QTestLib]] ([http://developer.kde.org/documentation/tutorials/writingunittests/writingunittests.html Original link])&lt;br /&gt;
:''Tutorial by [mailto:bradh@frogmouth.net Brad Hards] that describes how to write unit tests using the QTestLib framework. It is presented as an example based tutorial, and is still under development.''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Code_Checking|Semi-automatic ways to detect code errors]]&lt;br /&gt;
:''Techniques you can use to detect errors in KDE code''&lt;br /&gt;
&lt;br /&gt;
== Managing Configuration Data With KConfig ==&lt;br /&gt;
;[[Development/Tutorials/KConfig|Introduction To KConfig]]&lt;br /&gt;
:''An overview of the KConfig classes and how to use them in your application code''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Using KConfig XT|Using KConfig XT]]&lt;br /&gt;
:''Tutorial on how to efficiently use the KConfig XT framework.''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Updating KConfig Files|Updating KConfig Files]]&lt;br /&gt;
:''Tutorial on how to write an update script to keep changes in your application's config file format in sync with the user's already existing config file''&lt;br /&gt;
&lt;br /&gt;
== Services: Applications and Plugins ==&lt;br /&gt;
;[[Development/Tutorials/Services/Introduction|Introduction to the Services Framework]]&lt;br /&gt;
:''An overview of the services framework in KDE and what it provides the application developer. Covers the system configuration cache (SyCoCa), the source data files and what the indexed information can be used for.''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Services/Traders|Finding Services Using Trader Queries]]&lt;br /&gt;
:''How to find services, such as plugins or mimetypes, that are indexed in the SyCoCa using Trader Query Syntax''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Services/Plugins|Creating and Loading Plugins Using KService]]&lt;br /&gt;
:''Learn how to define custom plugin types, find installed plugins (including 3rd party plugins) and load them in an easy and portable fashion using KService.''&lt;br /&gt;
&lt;br /&gt;
== Localization ==&lt;br /&gt;
See also [[Localization|Localization portal]].&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Localization/Unicode|Introduction To Unicode]]&lt;br /&gt;
:''An introduction to what Unicode is as well as how to handle Unicode data in KDE applications.''&lt;br /&gt;
&lt;br /&gt;
; [[Development/Tutorials/Localization/i18n|Writing Applications With Localization In Mind]]&lt;br /&gt;
:''This tutorial covers what localization is, why it's important and how to ensure your application is ready to be localized. A must read for all application developers.''&lt;br /&gt;
&lt;br /&gt;
; [[Development/Tutorials/Localization/i18n Mistakes|Avoiding Common Localization Pitfalls]]&lt;br /&gt;
:''There are several common mistakes that prevent applications from being properly localized. Find out what they are and how to easily avoid them in this tutorial.''&lt;br /&gt;
&lt;br /&gt;
; [[Development/Tutorials/Localization/Building KDE's l10n Module|Building KDE's Localization Module]]&lt;br /&gt;
:''Building and installing language support from KDE's localization (l10n) module is a good idea for those working on applications in the main KDE repository. Doing so will allow you to test your application in another language and spot problem areas. Learn how to do just that in this tutorial.''&lt;br /&gt;
&lt;br /&gt;
; [[Development/Tutorials/Localization/i18n Build Systems|Incorporating i18n Into the Build System]]&lt;br /&gt;
:''Once your application is ready to be localized, the next step is to ensure that translation files are built automatically and kept up to date. This tutorial covers the necessary CMakeFiles.txt additions as well the process of distributing the resulting message catalogs with your application.''&lt;br /&gt;
&lt;br /&gt;
; [[Development/Tutorials/Localization/i18n Challenges|Common i18n Challenges and Solutions]]&lt;br /&gt;
:''This tutorial covers challenges that you may eventually run into such as translating handbooks and other data that exists outside of the source code, merging and handling obsolete .po files, dealing with freezes, coding in languages other than English and creating independent releases of or moving applications between KDE modules.''&lt;br /&gt;
&lt;br /&gt;
; [[Development/Tutorials/Localization/i18n_Semantics|Semantic Markup of Messages]]&lt;br /&gt;
:''To ensure consistent presentation and more meaningful representations of messages in applications, semantic markup can be applied to messages marked for translation using the KUIT system. This tutorial describes how this system works.''&lt;br /&gt;
&lt;br /&gt;
; [[Development/Tutorials/Localization/i18n Krazy|Automated i18n Code Checking]]&lt;br /&gt;
:''The Krazy code checker scans KDE's code and reports common i18n mistakes.''&lt;br /&gt;
&lt;br /&gt;
== Documentation ==&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/API_Documentation|API Documentation]]&lt;br /&gt;
:''This tutorial explains how to document your APIs properly.''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Man_Pages|Man Pages]]&lt;br /&gt;
:''Writing and Generating Reference Manual Pages.''&lt;br /&gt;
&lt;br /&gt;
;Source Code&lt;br /&gt;
: http://websvn.kde.org&lt;br /&gt;
&lt;br /&gt;
== Accessibility ==&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Accessibility|Accessibility]]&lt;br /&gt;
:''This tutorial will explain how to make your application accessible.''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Text-To-Speech|Text-To-Speech]]&lt;br /&gt;
:''How to utilize KDE's text to speech service in your application.''&lt;br /&gt;
&lt;br /&gt;
== Application Automation and Scripting ==&lt;br /&gt;
&lt;br /&gt;
=== D-Bus ===&lt;br /&gt;
; [[Development/Tutorials/D-Bus/Introduction|Introduction to D-Bus]]&lt;br /&gt;
:''A straight-forward introduction to the core concepts in D-Bus from an application developer's perspective, this tutorial covers what D-Bus is and how it can be used by applications.''&lt;br /&gt;
; [[Development/Tutorials/D-Bus/Accessing Interfaces|Accessing D-Bus Interfaces]]&lt;br /&gt;
:''A step-by-step guide to calling D-Bus methods and connecting to D-Bus signals using QtDBus.''&lt;br /&gt;
; [[Development/Tutorials/D-Bus/Intermediate_D-Bus|Intermediate D-Bus]]&lt;br /&gt;
:''Tips to make use of QtDBus when faced with problematic real-world interfaces.''&lt;br /&gt;
; [[Development/Tutorials/D-Bus/Creating Interfaces|Creating D-Bus Interfaces]]&lt;br /&gt;
:''Learn how to expose functionality in your application by creating and using custom D-Bus interfaces. Covers generating the XML descriptions, instantiating interfaces at run time and setting up the build system with CMake.''&lt;br /&gt;
; [[Development/Tutorials/D-Bus/CustomTypes|Using Custom Types with D-Bus]]: ''Learn how to use your own types in classes exported on D-Bus. Covers marhaling and unmarshaling of objects, the integration of custom types into XML descriptions and registering the custom types with the Qt Meta Object system.''&lt;br /&gt;
; [[Development/Tutorials/D-Bus/Autostart Services|D-Bus Autostart Services]]&lt;br /&gt;
:''Turn your application into a D-Bus autostart service with this tutorial. This D-Bus feature, also known as &amp;quot;D-Bus service activation&amp;quot;, will ensure that even when your application isn't running that D-Bus calls made to it will work by relying on the D-Bus daemon itself to start your app if and when needed.''&lt;br /&gt;
; [[Development/Tutorials/Porting_to_D-Bus|Porting from DCOP to D-Bus]]&lt;br /&gt;
: ''Port your applications from DCOP to D-Bus with this handy guide.''&lt;br /&gt;
&lt;br /&gt;
=== Konqueror ===&lt;br /&gt;
; [[Development/Tutorials/Creating Konqueror Service Menus|Creating Konqueror Service Menus]]&lt;br /&gt;
:''This tutorial shows you how to create mimetype-specific actions in Konqueror's context menu (aka &amp;quot;servicemenus&amp;quot;).''&lt;br /&gt;
&lt;br /&gt;
=== Kross ===&lt;br /&gt;
; [[Development/Tutorials/Kross/Introduction|Introduction to Kross]]&lt;br /&gt;
:''An introduction to the Kross Scripting Framework.''&lt;br /&gt;
&lt;br /&gt;
; [[Development/Tutorials/Kross/Hello_World|Hello World]]&lt;br /&gt;
:''A first application with working kross code.''&lt;br /&gt;
&lt;br /&gt;
; [[Development/Tutorials/Kross/Call_Functions_in_Kross|Calling Functions in Kross]]&lt;br /&gt;
:''Simple demonstration of calling scripting functions''&lt;br /&gt;
&lt;br /&gt;
; [[Development/Tutorials/Kross/Connecting_Signals_and_slots_in_Kross|Connecting Signals and Slots in Kross]]&lt;br /&gt;
:''Simple demonstration of connecting object signals with script slots''&lt;br /&gt;
&lt;br /&gt;
; [[Development/Tutorials/Kross/Scripts-as-Plugins|Scripts as Plugins with Kross]]&lt;br /&gt;
:''This tutorial provides a step-by-step introduction how to integrate scripts as plugins into a KDE application.''&lt;br /&gt;
&lt;br /&gt;
; [[Development/Tutorials/Kross/Script-Actions|Placing script actions in your application menus ]]&lt;br /&gt;
:''Simple demonstration on how to extend you application menus to execute script files.''&lt;br /&gt;
&lt;br /&gt;
; [[Development/Tutorials/Kross/ActionCollections|How to use an ActionCollection ]]&lt;br /&gt;
:''A small Tutorial on How to use Kross::ActionCollections.''&lt;br /&gt;
{{:KOffice/Plugin Tutorials}}&lt;br /&gt;
&lt;br /&gt;
=== SuperKaramba ===&lt;br /&gt;
; [[Development/Tutorials/SuperKaramba|SuperKaramba Tutorial]]&lt;br /&gt;
:''This tutorial provides an overview of SuperKaramba, theme files and scripting with Python, Ruby and JavaScript.''&lt;br /&gt;
&lt;br /&gt;
=== System Activity ===&lt;br /&gt;
&lt;br /&gt;
: [[Development/Tutorials/SystemActivity/Scripting|Writing script actions for the process's context menu]]&lt;br /&gt;
:''This tutorial shows how to add a context menu action to show custom information about a process.&lt;br /&gt;
&lt;br /&gt;
== Plugins and KParts ==&lt;br /&gt;
&lt;br /&gt;
; [[Development/Tutorials/Writing kontact plugins|Writing kontact plugins]]:''Kontact plugins are KParts. This tutorial describes how you can write one.''&lt;br /&gt;
&lt;br /&gt;
; [[Development/Tutorials/Using KParts|Using KParts]]:''Learn how to load a KPart into an application window.''&lt;br /&gt;
&lt;br /&gt;
; [[Development/Tutorials/Writing Qt Designer Plugins|Writing Qt Designer Plugins]]:''Add your widgets to Qt Designer and thus make them usable in UI files.''&lt;br /&gt;
&lt;br /&gt;
== Search and Metadata ==&lt;br /&gt;
&lt;br /&gt;
=== Strigi ===&lt;br /&gt;
&lt;br /&gt;
; [[Development/Tutorials/Writing file analyzers|Writing file analyzers]]&lt;br /&gt;
:''File analyzers extract data from files to display in the file dialogs and file managers. The data gathered this way is also used to search for files. KDE4 allows the use of multiple analyzers per file type. This tutorial describes how you can write new analyzers.''&lt;br /&gt;
&lt;br /&gt;
=== [http://nepomuk.kde.org Nepomuk] ===&lt;br /&gt;
&lt;br /&gt;
; [[Development/Tutorials/Metadata/Nepomuk/Quickstart|Nepomuk Quickstart]]&lt;br /&gt;
:''How to use Nepomuk resources in a quick and painless way without much fuss.''&lt;br /&gt;
&lt;br /&gt;
; [[Development/Tutorials/Metadata/Nepomuk/RDFIntroduction|RDF and Ontologies in Nepomuk]]&lt;br /&gt;
:''An introduction to RDF and the usage of ontologies in Nepomuk.''&lt;br /&gt;
&lt;br /&gt;
; [[Development/Tutorials/Metadata/Nepomuk/DataLayout|Data Layout in Nepomuk]]&lt;br /&gt;
:''An overview of which and how data is stored in Nepomuk.''&lt;br /&gt;
&lt;br /&gt;
; [[Development/Tutorials/Metadata/Nepomuk/Resources|Handling Resources with Nepomuk]]&lt;br /&gt;
:''Nepomuk is the KDE library which provides easy access to metadata in the Nepomuk system. Learn how to make your application create and read metadata using the Nepomuk system.''&lt;br /&gt;
&lt;br /&gt;
; [[Development/Tutorials/Metadata/Nepomuk/ResourceGenerator|Using the Nepomuk Resource Generator]]&lt;br /&gt;
:''Nepomuk includes a resource generator which creates convenience classes for handling metadata.''&lt;br /&gt;
&lt;br /&gt;
; [[Development/Tutorials/Metadata/Nepomuk/NepomukQuery|Using the Nepomuk Query API]]&lt;br /&gt;
:''Starting with KDE 4.4 Nepomuk provides a desktop query API.''&lt;br /&gt;
&lt;br /&gt;
; [[Development/Tutorials/Metadata/Nepomuk/AdvancedQueries|Advanced Queries]]&lt;br /&gt;
:''The real power of Nepomuk can only be exposed when performing fancy queries on the data repository. This tutorial provides an introduction to semantic and full text queries in Nepomuk.''&lt;br /&gt;
&lt;br /&gt;
; [[Development/Tutorials/Metadata/Nepomuk/NepomukServer|The Nepomuk Server and the Architecture of the Nepomuk subsystem]]&lt;br /&gt;
:''The Nepomuk Server hosts the main Nepomuk data repository and can be accessed directly via a Soprano API.''&lt;br /&gt;
&lt;br /&gt;
; [[Development/Tutorials/Metadata/Nepomuk/NepomukServices|Nepomuk Services]]&lt;br /&gt;
:''The Nepomuk Server manages a set of Nepomuk services.''&lt;br /&gt;
:* [[Development/Tutorials/Metadata/Nepomuk/StorageService|Storage Service]] ''The probably most important service hosts the Nepomuk data repository using [http://soprano.sourceforge.net Soprano].''&lt;br /&gt;
:* [[Development/Tutorials/Metadata/Nepomuk/OntologyLoaderService|Ontology Loader]] ''Makes sure installed ontologies such as RDF, RDFS, NRL, or Xesam are loaded into the storage repository.''&lt;br /&gt;
:* [[Development/Tutorials/Metadata/Nepomuk/FileWatchService|File Watch Service]] ''Monitors the file system for changes and updates the file resource paths and URIs in Nepomuk.''&lt;br /&gt;
:* [[Development/Tutorials/Metadata/Nepomuk/StrigiService|Strigi Service]] ''Controls Strigi, the file indexing tool which extracts metadata from files and stores it into the storage repository.''&lt;br /&gt;
:* [[Development/Tutorials/Metadata/Nepomuk/QueryService|Query Service]] ''Provides persistant query folders.''&lt;br /&gt;
&lt;br /&gt;
; [[Development/Tutorials/Metadata/Nepomuk/TipsAndTricks|Nepomuk Tips and Tricks]]&lt;br /&gt;
:''A set of tips and tricks for development with Nepomuk and Soprano. This is a must-read if you intend to use Nepomuk in your application or hack on it directly.''&lt;br /&gt;
&lt;br /&gt;
== Hardware Awareness (Solid) ==&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Solid_Tutorials|Introduction to Solid]]&lt;br /&gt;
:''An introduction to using the Solid hardware discovery and interaction system in KDE applications.''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Solid_Network_Tutorial|Accessing Network Information]]&lt;br /&gt;
:''How to use the Solid system to get information about the network''&lt;br /&gt;
&lt;br /&gt;
== Authorization and Privilege escalation (KAuth) ==&lt;br /&gt;
; [[Development/Tutorials/KAuth/KAuth_Basics|KAuth Basics]]&lt;br /&gt;
:''An overview of concepts and basic knowledge required to understand and use KAuth effectively''&lt;br /&gt;
; [[Development/Tutorials/KAuth/KAuth_Actions|Using KAuth actions in your application]]&lt;br /&gt;
:''How to execute KAuth actions in your application, and how to integrate them tightly into your UI''&lt;br /&gt;
; [[Development/Tutorials/KAuth/Helper_HowTo|Creating a KAuth helper to perform a privileged action]]&lt;br /&gt;
:''You will learn how to use KAuth's helpers and escalation facilities, and how to seamlessly make a privileged and non privileged portion of your application interact''&lt;br /&gt;
; [[Development/Tutorials/KAuth/KCM_HowTo|Creating a KCM requiring authorization upon saving]]&lt;br /&gt;
:''Learn how to use the high level KCModule API to create KCModules handling authorization, and its UI integration, on their own''&lt;br /&gt;
&lt;br /&gt;
== Multimedia (Phonon) ==&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Phonon/Introduction|Phonon]]&lt;br /&gt;
:''How to start with the multimedia API''&lt;br /&gt;
&lt;br /&gt;
:''How to compile and use Phonon and its GStreamer backend on Linux using Qt 4.3.x''&lt;br /&gt;
::''This article gives you a quick brief of how you can use checkout, compile Phonon and its GStreamer backend on GNU/Linux with just Qt 4.3.x. Towards the end, the article also describes how a developer can make use of Phonon to create simple audio and video players. You can read the article [http://www.vcreatelogic.com/oss/docs/CompilingPhononOnLinux.pdf here]. You can download the editable OpenDocumentText file from [http://www.prashanthudupa.com/phonon/CompilingPhononOnLinux.odt here].''&lt;br /&gt;
&lt;br /&gt;
== Plasma ==&lt;br /&gt;
&lt;br /&gt;
See [[Development/Tutorials/Plasma|Plasma tutorials]].&lt;br /&gt;
&lt;br /&gt;
== Communication (Decibel) ==&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Decibel/GettingStarted|Getting started with Decibel]]&lt;br /&gt;
:''This tutorial describes how to set up Decibel.''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Decibel/Handling_TextChannels|Handling TextChannels]]&lt;br /&gt;
:''This tutorial introduces the basics of handling incoming TextChannels by guiding you through building a simple text chat application.''&lt;br /&gt;
&lt;br /&gt;
== Personal Information Management (Akonadi) ==&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Akonadi/Application|Using Akonadi in Applications]]&lt;br /&gt;
:''Displaying and modifying data provided by Akonadi''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Akonadi/Resources|Developing Akonadi Resources]]&lt;br /&gt;
:''Akonadi Resources are agent programs which transport PIM data between Akonadi and a backend (files, servers, etc)''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Akonadi/SerializerPlugin|Using custom data types with Akonadi]]&lt;br /&gt;
:''Akonadi can handle arbitrary data as item payloads through the use of a plugin based serialization framework''&lt;br /&gt;
&lt;br /&gt;
;[[Development/AkonadiPorting|Porting Applications which use KResource API]]&lt;br /&gt;
:''Applications using KDE's now deprecated KResource APIs, e.g. KABC or KCal, need to be ported to use their Akonadi equivalents''&lt;br /&gt;
&lt;br /&gt;
== Kate / Kwrite ==&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Kate/KTextEditor Plugins|Getting started with KTextEditor plugins]]&lt;br /&gt;
:''Creating your first KTextEditor plugin''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Kate/KTextEditor_Plugins_Advanced|Developing a plugin with configuration dialog]]&lt;br /&gt;
:''Adding a configuration dialog to the Time &amp;amp; Date example''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Kate/KTextEditor_Example|A small Editor]]&lt;br /&gt;
:''Create a small application using KTextEditor''&lt;br /&gt;
&lt;br /&gt;
== KDevelop ==&lt;br /&gt;
&lt;br /&gt;
;[[Development/KDevelop-PG-Qt_Introduction|KDevelop-PG-Qt Introduction]]&lt;br /&gt;
:''Information on the KDevelop parser generator, useful for language plugins.''&lt;br /&gt;
&lt;br /&gt;
==Printing==&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Printing Hello World|Hello World]]&lt;br /&gt;
:''Introduction to the KDE printing system''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Printing Print Dialog|Print Dialog]]&lt;br /&gt;
:''Using the KDE print dialog''&lt;br /&gt;
&lt;br /&gt;
== kioslaves ==&lt;br /&gt;
* [[Development/Tutorials/KIO Slaves/Using KIO Slaves in your Program|Using kioslaves in your Program]]&lt;br /&gt;
* [[Development/Tutorials/KIO Slaves/Hello World|Creating a Hello-World kioslave]]&lt;br /&gt;
&lt;br /&gt;
== Collaboration ==&lt;br /&gt;
&lt;br /&gt;
=== Open Collaboration Services (libattica) ===&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Collaboration/Attica/Introduction|Introduction to Attica]]&lt;br /&gt;
:''In this tutorial a simple widget showing information about a Person on the server is created.''&lt;br /&gt;
&lt;br /&gt;
=== Get Hot New Stuff  ===&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Collaboration/HotNewStuff/Introduction|Get Hot New Stuff 3 - Download]] &lt;br /&gt;
:''How to use KHotNewStuff3 in your application.''&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Collaboration/HotNewStuff/Updates|Get Hot New Stuff 3 - Checking for Updates]] &lt;br /&gt;
:''How to check if updates for installed stuff are available without showing the dialog/widget.''&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Collaboration/HotNewStuff/Upload|Get Hot New Stuff 3 - Upload]] &lt;br /&gt;
:''How to add an upload dialog to your application.''&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Old links for KNS2 and KNS1 content:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/K Hot New Stuff2|Introduction to Get Hot New Stuff 2]] &lt;br /&gt;
:''A short tutorial about how to use KHotNewStuff2 in your application. Deprecated, use version 3'' &lt;br /&gt;
;[[Development/Tutorials/Introduction to Get Hot New Stuff|Introduction to Get Hot New Stuff]] &lt;br /&gt;
:''An introduction to the developer-friendly network update system that allows KDE applications to fetch new application data at runtime in a user friendly manner.''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/KNewStuffSecure|KNewStuff Secure]] ([http://developer.kde.org/documentation/tutorials/knewstuffsecure/index.html Original Link]) &lt;br /&gt;
:''Tutorial showing how to share resources in a secured way (KDE 3.4 and later).'' By András Mantia &amp;amp;lt;amantia@kde.org&amp;amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Goya ==&lt;br /&gt;
; [[Development/Tutorials/Introduction to Goya usage|Introduction to Goya usage]]&lt;br /&gt;
:''An introduction for the Goya subsystem usage, which allows you to easily add widgets to your itemviews and connect their signals to your code, as they were real widgets.''&lt;br /&gt;
&lt;br /&gt;
; [[Development/Tutorials/Introduction to Goya usage 2|Introduction to Goya usage (part 2)]]&lt;br /&gt;
:''The second part of the tutorial, with a slightly more complex example than the first part.''&lt;br /&gt;
&lt;br /&gt;
== Other programming languages ==&lt;br /&gt;
&lt;br /&gt;
=== Python ===&lt;br /&gt;
&lt;br /&gt;
;[http://www.learningpython.com/2008/09/20/an-introduction-to-pyqt/ An Introduction to PyQt]&lt;br /&gt;
:''Starting off''&lt;br /&gt;
&lt;br /&gt;
;[http://lateral.netmanagers.com.ar/stories/BBS47.html PyQt by Example]&lt;br /&gt;
:''Another introduction to PyQt''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Languages/Python/PyKDE_WebKit_Tutorial|PyKDE WebKit Tutorial]]&lt;br /&gt;
:''A simple web browser application in PyKDE''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Python introduction to signals and slots|101 Introduction to signals and slots]]&lt;br /&gt;
:''A simple introduction to Qt's signal and slot architecture.''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Languages/Python/PyKDE_DBus_Tutorial|PyKDE DBus Tutorial]]&lt;br /&gt;
:''An introduction to DBus communication using PyKDE''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Languages/Python/PyKDE_Knotify_Tutorial|PyKDE KNotify Tutorial]]&lt;br /&gt;
:''An introduction to Knotify (Notifications and KJobs) using PyKDE''&lt;br /&gt;
&lt;br /&gt;
=== Ruby ===&lt;br /&gt;
&lt;br /&gt;
;[http://developer.kde.org/language-bindings/ruby/kde3tutorial/index.html KDE Ruby Korundum tutorial]&lt;br /&gt;
:''A ruby version of Antonio Larrosa Jim&amp;amp;eacute;nez's KDE tutorial by Richard Dale. See the [[Development/Languages/Ruby|Ruby Developers Corner]] for Qt tutorials and other info.''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Qt4_Ruby_Tutorial|Qt4 Ruby Tutorial]]&lt;br /&gt;
:''Nokia's fabulous introductory tutorial to Qt, translated to Ruby.''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Plasma/RubyApplet|Creating a Plasma Widget in Ruby]]&lt;br /&gt;
:''Tutorial that shows how to create your first Plasma Applet using the Ruby language.''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Developing_Qt4_Applications_using_Qt_Designer_and_Ruby_on_Kubuntu|Developing Qt4 Applications using Qt Designer and Ruby on Kubuntu]]&lt;br /&gt;
:''Tutorial that shows how to design a simple User Interface in Qt Designer and then use the resulting widget in a Qt Ruby application we build from scratch.''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Languages/Ruby/Ruby-Qt/KDE_Book|Ruby-Qt/KDE Book]]&lt;br /&gt;
:''There is also an approach to create an Ruby-Qt/KDE Book under a free license. The content will be created in this wiki.''&lt;br /&gt;
&lt;br /&gt;
=== Shell ===&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Shell_Scripting_with_KDE_Dialogs|Shell Scripting with KDE dialogs]] ([http://developer.kde.org/documentation/tutorials/kdialog/t1.html Original Link]) &lt;br /&gt;
:''Tutorial by [mailto:bradh@frogmouth.net Brad Hards] that describes how to use KDE dialogs in shell scripts with kdialog. It is presented as an example based tutorial.''&lt;br /&gt;
&lt;br /&gt;
== Graphics Programming ==&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Graphics/Performance|QPainter Perfomance]]&lt;br /&gt;
:''Hints on avoiding common mistakes leading to poor performance when using QPainter''&lt;br /&gt;
&lt;br /&gt;
== Using the KDE Games Libraries ==&lt;br /&gt;
;[[Development/Tutorials/Games/KStandardGameAction| KStandardGameAction]]&lt;br /&gt;
:''Using libkdegames to make your game fit the kdegames standard''&lt;br /&gt;
;[[Development/Tutorials/Games/Highscores| Highscores]]&lt;br /&gt;
:''Implementing a simple highscore table into your game''&lt;br /&gt;
;[[Development/Tutorials/Games/Theme Selector| Theme Selector]]&lt;br /&gt;
:''Using the libkdegames theme selection dialog''&lt;br /&gt;
;[[Development/Tutorials/Games/Palapeli Patterns| Palapeli Slicers]]&lt;br /&gt;
:''Creating a slicer plugin for Palapeli''&lt;br /&gt;
&lt;br /&gt;
=== KGLEngine ===&lt;br /&gt;
;[[Development/Tutorials/Games/kglengine/kglengine-simpleBox| installation and your first KGLItem]]&lt;br /&gt;
:''start your first kglengine application''&lt;br /&gt;
;[[Development/Tutorials/Games/KGLEngine2d| kglpong]]&lt;br /&gt;
:''Now use our knowledge to make a pong''&lt;br /&gt;
&lt;br /&gt;
=== KALEngine ===&lt;br /&gt;
;[[Development/Tutorials/Games/KALEngine| Play hello word sound]]&lt;br /&gt;
:''Using KALEngine for games sound development using openAL''&lt;br /&gt;
;[[Development/Tutorials/Games/KALEngine-music| Play music]]&lt;br /&gt;
:''Using KALEngine to play music in a stream''&lt;br /&gt;
&lt;br /&gt;
== Using the KDE PIM Libraries ==&lt;br /&gt;
;[[Development/Tutorials/PIM/ical| iCalendar functionality]]&lt;br /&gt;
:''Using kcal to manage iCalendar files''&lt;br /&gt;
&lt;br /&gt;
== Other tutorials ==&lt;br /&gt;
&lt;br /&gt;
=== 2D Plotting (KPlotWidget) ===&lt;br /&gt;
;[[Development/Tutorials/KPlotWidget|Using the KDE data-plotting widget]]&lt;br /&gt;
:''This tutorial introduces KPlotWidget, which is used for 2-D data plotting.  It includes information on simple usage of the widget (including adding and modifying data sets, and customizing the plot axes and labels), and advanced customization (including extending the widget through sub-classing).''&lt;br /&gt;
&lt;br /&gt;
=== Spelling and Grammar Checking (Sonnet) ===&lt;br /&gt;
;[[Development/Tutorials/Sonnet/SonnetTutorial|Adding spell-checking or grammar-checking to KDE applications]]&lt;br /&gt;
:''This tutorial introduces Sonnet and how one may use it to add language correction to your KDE application. Sonnet's auxiliary features shall be described in a separate tutorial.''&lt;br /&gt;
&lt;br /&gt;
=== Pixmap cache (KPixmapCache) ===&lt;br /&gt;
;[[Development/Tutorials/KPixmapCache|Using the KDE pixmap cache]]&lt;br /&gt;
:''This tutorial shows how to use KPixmapCache to cache e.g. pixmaps generated from SVGs or some data.''&lt;br /&gt;
&lt;br /&gt;
=== Using MarbleWidget (Marble) ===&lt;br /&gt;
;[[Development/Tutorials/MarbleWidget|Using MarbleWidget]]&lt;br /&gt;
:''This short tutorial describes how to use the MarbleWidget in your project''&lt;br /&gt;
&lt;br /&gt;
=== Using local SCM for KDE development ===&lt;br /&gt;
;[[Development/Tutorials/Git|Using Git to develop for KDE]]&lt;br /&gt;
:''This tutorial shows how to use Git to develop for KDE''&lt;br /&gt;
&lt;br /&gt;
=== Kwin effect tutorial (blog) ===&lt;br /&gt;
;[http://blog.martin-graesslin.com/blog/?p=258 blog by Martin Graesslin]&lt;br /&gt;
:''This tutorial guides you through the development of a simple KWin effect''&lt;br /&gt;
&lt;br /&gt;
=== Implementing KSysGuard sensors and adding them ===&lt;br /&gt;
;[[Development/Tutorials/Sensors]]&lt;br /&gt;
:''This tutorial shows how to write and KSysGuard sensor and connect it to the systray.''&lt;br /&gt;
Runners&lt;br /&gt;
&lt;br /&gt;
=== Porting an application from KSystemTrayIcon to KStatusNotifierItem ===&lt;br /&gt;
;[[Development/Tutorials/PortToKStatusNotifierItem]]&lt;br /&gt;
:''This tutorials shows how to port an application using KSystemTrayIcon to KStatusNotifierItem''&lt;br /&gt;
&lt;br /&gt;
=== Using the KDE Wallet API for safe storage ===&lt;br /&gt;
;[[Development/Tutorials/KWallet]]&lt;br /&gt;
:&amp;quot;Brief introduction to the KWallet API which can be used for storing all kinds of sensitive information.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== KDE2 and KDE3 Materials ==&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/KDE3|KDE3 Tutorials]]&lt;br /&gt;
:''These tutorials cover topics related to KDE3.''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/KDE2|KDE2 Tutorials]]&lt;br /&gt;
:''These tutorials cover topics related to KDE2.''&lt;br /&gt;
&lt;br /&gt;
[[Category:KDE4]]&lt;/div&gt;</summary>
		<author><name>Hefee</name></author>	</entry>

	</feed>