Dev Week -- Fun with Python Plasmoids -- agateau and Riddell -- Mon Aug 31st, 2009


(04:02:23 PM) agateau: Shall we start now?
(04:02:25 PM) jawnsy: *round of applause for Riddell and agateau* :-)
(04:02:43 PM) agateau: thanks jawnsy :)
(04:03:12 PM) agateau: Riddell and myself are now going to introduce you to plasmoid developments in Python
(04:03:37 PM) Riddell: and we want you to follow along at home!
(04:03:37 PM) agateau: I'll do a short intro of Plasma and Python, then Riddell will take you through your first plasmoid
(04:04:04 PM) agateau: and I'll come back with more widgetry for your plasmoids
(04:04:14 PM) agateau: First things first,
(04:04:22 PM) agateau: What is Plasma?
(04:04:36 PM) agateau: It's the new implementation of the desktop
(04:04:39 PM) agateau: in KDE4
(04:05:20 PM) agateau: Riddell reminds me I should tell you what packages you need to install while I talk:
(04:05:36 PM) agateau: apt-get install kdebase-workspace-bin plasma-scriptengine-python
(04:05:41 PM) agateau: and you should be all set
(04:06:06 PM) agateau: so, Plasma is based on Qt Graphics View framework, which is, quoting Qt doc:
(04:06:13 PM) agateau: "Graphics View provides a surface for managing and interacting with a large
(04:06:13 PM) agateau: number of custom-made 2D graphical items, and a view widget for visualizing the
(04:06:13 PM) agateau: items, with support for zooming and rotation."
(04:06:29 PM) agateau: it can use hardward acceleration, and be themed with SVG files
(04:06:40 PM) agateau: what are plasmoid?
(04:07:00 PM) agateau: plasmoids are little gadgets you can put on your desktop
(04:07:08 PM) agateau: the whole KDE4 desktop is made of plasmoids
(04:07:17 PM) agateau: (taskbar, pager, K menu, clock, systray...)
(04:07:32 PM) agateau: some examples:
(04:07:38 PM) agateau:
(04:07:45 PM) agateau:
(04:08:04 PM) agateau: Plasmoids can be developed in C++, JavaScript, Ruby...
(04:08:06 PM) agateau: and Python
(04:08:12 PM) agateau: our beloved language
(04:08:44 PM) agateau: Python is an interpreted, dynamic programming language
(04:08:54 PM) agateau: it's simple yet powerful,
(04:08:59 PM) agateau: and very versatile
(04:09:13 PM) agateau: it can be used for throw away scripts, desktop applications, web servers...
(04:09:18 PM) agateau: and plasmoids
(04:09:28 PM) agateau: as Riddell is now going to show you...
(04:09:35 PM) Riddell: we had some questions first
(04:09:42 PM) Riddell: 21:05 < wizz_> is plasmoid available for ubuntu 9.04 and python2.6?
(04:09:55 PM) Riddell: yes, you need to install python-plasma in jaunty
(04:10:06 PM) Riddell: as well as kdebase-workspace-bin
(04:10:17 PM) Riddell: 21:06 < msp301> will plasma work under gnome??
(04:10:23 PM) Riddell: yes, you can use the plasmoidviewer app
(04:10:37 PM) Riddell: or you can try running plasma-desktop on top of gnome, goodness knows how that will end up
(04:11:05 PM) Riddell: so let's get coding!
(04:11:23 PM) Riddell: a basic plasmoid is made up of a metadata file
(04:11:38 PM) Riddell: which tells plasma the name and other vital information about the plasmoid
(04:11:42 PM) Riddell: and some code
(04:11:54 PM) Riddell: that all gets zipped up
(04:12:10 PM) Riddell: and finally you install the zip file so you can run the plasmoid
(04:12:23 PM) Riddell: so start off in a new directory
(04:12:43 PM) Riddell: and make the directories needed for our "hello-python" plasmoid
(04:12:52 PM) Riddell: mkdir -p hello-python/contents/code
(04:13:15 PM) Riddell: cd hello-python
(04:13:25 PM) Riddell: here we'll put our metadata which is in .desktop format
(04:13:44 PM) Riddell: [Desktop Entry]
(04:13:44 PM) Riddell: Encoding=UTF-8
(04:13:44 PM) Riddell: Name=Hello Python
(04:13:44 PM) Riddell: Type=Service
(04:13:44 PM) Riddell: ServiceTypes=Plasma/Applet
(04:13:46 PM) Riddell: Icon=chronometer
(04:14:08 PM) Riddell: is the top, that gives it a name and tells plasma that it's an applet, also gives it an icon to use for the Add Applet dialogue
(04:14:38 PM) Riddell: next some vital plasma info lines
(04:14:39 PM) Riddell: X-Plasma-API=python
(04:14:40 PM) Riddell: X-Plasma-MainScript=code/
(04:14:58 PM) Riddell: so plasma knows it's looking for Python and it knows what code it's looking for
(04:15:23 PM) Riddell: finally some plugin info lines
(04:15:25 PM) Riddell: X-KDE-PluginInfo-Author=Simon Edwards
(04:15:26 PM) Riddell:
(04:15:26 PM) Riddell: X-KDE-PluginInfo-Name=hello-python
(04:15:26 PM) Riddell: X-KDE-PluginInfo-Version=1.0
(04:15:26 PM) Riddell: X-KDE-PluginInfo-Website=
(04:15:28 PM) Riddell: X-KDE-PluginInfo-Category=Examples
(04:15:31 PM) Riddell: X-KDE-PluginInfo-Depends=
(04:15:33 PM) Riddell: X-KDE-PluginInfo-License=GPL
(04:15:36 PM) Riddell: X-KDE-PluginInfo-EnabledByDefault=true
(04:15:38 PM) Riddell: 21:15 < keffie_jayx> Riddell: what is the file name .Desktop?
(04:15:48 PM) Riddell: this all goes in a file called "metadata.desktop"
(04:15:57 PM) Riddell: and here's the full thing
(04:15:58 PM) Riddell:
(04:16:32 PM) Riddell: so if you were following closely, you'll have worked out that code/ will be where the real code is
(04:17:05 PM) Riddell: cd contents/code  and emacs
(04:17:13 PM) Riddell: we all use emacs don't we? :)
(04:17:36 PM) Riddell: sorry   emacs
(04:18:03 PM) Riddell: python always starts with importing the relevant libraries
(04:18:07 PM) Riddell: in this case it's PyQt and PyKDE
(04:18:10 PM) Riddell: from PyQt4.QtCore import *
(04:18:10 PM) Riddell: from PyQt4.QtGui import *
(04:18:10 PM) Riddell: from PyKDE4.plasma import Plasma
(04:18:10 PM) Riddell: from PyKDE4 import plasmascript
(04:18:56 PM) Riddell: we want to make a class inheriting from the plasma Applet base class
(04:19:28 PM) Riddell: if you know object orientated programming, python is very simple
(04:19:30 PM) Riddell: class HelloPython(plasmascript.Applet):
(04:19:30 PM) Riddell:     def __init__(self,parent,args=None):
(04:19:30 PM) Riddell:         plasmascript.Applet.__init__(self,parent)
(04:19:59 PM) Riddell: that's the class header and the constructor, which just calls the parent constructor
(04:20:32 PM) Riddell: we want an init() method to do some basic setup
(04:20:32 PM) Riddell:     def init(self):
(04:20:32 PM) Riddell:         self.setHasConfigurationInterface(False)
(04:20:32 PM) Riddell:         self.resize(125, 125)
(04:20:32 PM) Riddell:         self.setAspectRatioMode(Plasma.Square)
(04:21:03 PM) Riddell: Plasma prefers we don't do the basic setup in the constructor so it gives us this separate init() method instead
(04:21:26 PM) Riddell: the code should be pretty self readable because KDE APIs are like that, and Python is clean as programming languages come
(04:21:51 PM) Riddell: the main body we're interested in is the paint method which will paint our hello message
(04:21:55 PM) Riddell:     def paintInterface(self, painter, option, rect):
(04:21:55 PM) Riddell:
(04:21:55 PM) Riddell:         painter.setPen(Qt.white)
(04:21:55 PM) Riddell:         painter.drawText(rect, Qt.AlignVCenter | Qt.AlignHCenter, "Hello Kubuntu!")
(04:21:58 PM) Riddell:         painter.restore()
(04:22:40 PM) Riddell: which is also pretty self explanatory, it uses the painting object to put some text on the screen
(04:23:11 PM) Riddell: finally plasma needs us to create the applet object from our class
(04:23:12 PM) Riddell: def CreateApplet(parent): return HelloPython(parent)
(04:23:26 PM) Riddell: the whole code can be found here
(04:24:21 PM) Riddell: next we need to package it
(04:24:31 PM) Riddell: go back to your top level directory and put it into a zip file
(04:24:37 PM) Riddell: zip -r hello-python hello-python
(04:24:47 PM) Riddell: finally install it with plasmapkg
(04:24:57 PM) Riddell: plasmapkg -i
(04:25:20 PM) Riddell: it will say if it installed correctly or not
(04:25:31 PM) Riddell: if it's installed correctly you should be able to add it as a widget to your plasma desktop
(04:25:40 PM) Riddell: or if you're not using KDE you can use plasmoidviewer
(04:25:48 PM) Riddell: plasmoidviewer hello-python
(04:26:28 PM) Riddell: with any luck it'll look a bit like this
(04:26:47 PM) Riddell: you can get the zip file from incase you didn't get all the code
(04:27:12 PM) Riddell: whoever manages that successfully first gets a free beer
(04:27:44 PM) Riddell: agateau: want to take them to the next level?
(04:27:55 PM) agateau: Riddell: yup!
(04:28:18 PM) agateau: So,
(04:28:26 PM) agateau: We will continue with widgets
(04:28:59 PM) agateau: So far the created plasmoid draws text itself in the paintInterface() method
(04:29:14 PM) agateau: This is quite powerful because you get a very fine control over what you want to draw
(04:29:33 PM) agateau: but it can also lead to inconsistency if every plasmoid draw things their way
(04:29:59 PM) agateau: To help with this, plasma comes with a quite complete set of widgets
(04:30:39 PM) agateau: You can use regular Qt widgets in a Plasmoid,
(04:30:56 PM) agateau: but using Plasma widgets is a better idea because they will match the plasma theme
(04:31:10 PM) agateau: and you will get fancy effects for the same price
(04:31:30 PM) agateau: A good example of a plasmoid which uses Plasma widgets is powerdevil
(04:31:40 PM) agateau:
(04:32:07 PM) agateau: as you can see, we can use labels, slidesrs, comboboxes, buttons...
(04:32:13 PM) agateau: quite a few things
(04:32:36 PM) agateau: let's modify the previous example to use widgets instead of custom painting
(04:33:19 PM) agateau: I suggest you make a copy of the hello-python dir
(04:33:29 PM) agateau: just make sure you rename the plasmoid
(04:33:37 PM) agateau: - edit metadata.desktop
(04:34:30 PM) agateau: - change X-KDE-PluginInfo-Name value to hello-widget
(04:34:41 PM) agateau: now go to our new copy of
(04:35:05 PM) agateau: We no longer need paintInterface() so we can remove it
(04:35:25 PM) agateau: instead we are going to add some lines to the init() method
(04:35:41 PM) agateau: First we create a label:
(04:35:42 PM) agateau: label = Plasma.Label(self.applet)
(04:35:52 PM) agateau: And define some text in it:
(04:36:01 PM) agateau: label.setText("Hello world!")
(04:36:30 PM) agateau: Notice that we used self.applet, not self when we created the label
(04:37:05 PM) agateau: This is little Python Plasma quirk, just remember to use self.applet as a parent for your widgets and all will be fine
(04:37:26 PM) agateau: If you try it like this, your plasmoid won't behave very well when resized
(04:37:54 PM) agateau: We need to assign a layout to the plasmoid and add our label to it
(04:38:29 PM) agateau: a layout is like an organizer: it ensure widgets are correctly aligned and resized when the plasmoid gets resized
(04:38:36 PM) agateau:  self.layout = QGraphicsLinearLayout(Qt.Horizontal, self.applet)
(04:38:47 PM) agateau: Here it is, an horizontal layout
(04:39:00 PM) agateau: now we add our label to it
(04:39:08 PM) agateau: self.layout.addItem(label)
(04:39:20 PM) agateau: And it should be good
(04:39:46 PM) agateau: You can give it a try in the same way Riddell shown you with the first plasmoid
(04:40:09 PM) agateau: cd to the hello-widget/ dir
(04:40:18 PM) agateau: zip -r ../ .
(04:40:28 PM) agateau: plasmoidviewer hello-widget
(04:40:34 PM) agateau: oups...
(04:40:42 PM) agateau: forgot the install step
(04:40:50 PM) agateau: plasmapkg -i ../
(04:41:00 PM) agateau: then plasmoidviewer hello-widget
(04:41:27 PM) agateau: (actually, you can install from the dir directly, "plasmapkg -i ." will work fine)
(04:42:03 PM) agateau: Did you get a widget-powered "Hello world" plasmoid?
(04:42:45 PM) agateau: If you want to try more widgets, you can have a look at the list of Plasma classes:
(04:42:50 PM) agateau:
(04:43:09 PM) agateau: (It's C++, but the doc is usable in Python with no changes)
(04:43:21 PM) agateau: Since KDE 4.3, there is even a VideoWidget!
(04:44:03 PM) agateau: With this, I am going to leave you in the expert hands of Riddell
(04:44:14 PM) Riddell: we had some questions over in -chat
(04:44:15 PM) Riddell: 21:28 < NamShub> Question: I would like to learn how to add a configuration dialog and read/write settings from this dialog
(04:44:31 PM) Riddell: which was well answered by fliegenderfrosch
(04:44:33 PM) Riddell: 21:31 < fliegenderfrosch> NamShub: setHasConfigInterface(True), then you reimplement the functions showConfigurationInterface(self) and createConfigurationInterface(self, parent)
(04:44:37 PM) Riddell: 21:31 < fliegenderfrosch> showConfigurationInterface(self) basically just creates a KPageDialog and calls createConfigureInterface with it as argument
(04:44:51 PM) Riddell: as I said KDE APIs are designed to be easy to read so just read the docs
(04:45:18 PM) Riddell: I also pointed NamShub to plasma-widget-googlecalendar as a larger example which has recently been added to karmic
(04:45:38 PM) Riddell: fliegenderfrosch wanted to know when the apidocs for PyKDE 4.3 are available?
(04:45:55 PM) Riddell: that'll happen when Sime gets some spare time, he maintains PyKDE single handed and is quite the hero
(04:46:08 PM) Riddell: in the mean time the 4.2 API is pretty good
(04:46:33 PM) Riddell: and you can always use the C++ API docs and convert them easily enough
(04:47:34 PM) Riddell: I'll quickly take you through a more complete example
(04:48:00 PM) Riddell: copy your hello-widget directory to powerchart
(04:48:23 PM) Riddell: and edit metadata.desktop to give it a Name=Power Chart and X-KDE-PluginInfo-Name=powerchart
(04:48:41 PM) Riddell: I'll not paste the whole of the code but you can find it here
(04:48:59 PM) Riddell: this example is a battery monitor
(04:49:06 PM) Riddell: it uses a powerful tool in Plasma, the data engine
(04:49:32 PM) Riddell: data engines are plugins which provide some useful data, could be about the network status or could be about a blog feed
(04:49:52 PM) Riddell: the engine can be used by several applets if they have a need for it
(04:50:27 PM) Riddell: Plasma's API is full of useful GUI widgets as agateau said earlier
(04:50:42 PM) Riddell: and this example uses a widget called a SignalPlotter:  self.chart = Plasma.SignalPlotter(self.applet)
(04:50:48 PM) Riddell: which draws a chart for us
(04:51:18 PM) Riddell: the connectToEngine() method creates a dataengine of type 'soliddevice'
(04:51:33 PM) Riddell: Solid is the KDE library which gives us information about all sorts of hardware
(04:51:47 PM) Riddell: it's cross platform so it'll work on Linux, BSD, Windows and more
(04:52:13 PM) Riddell: with a simple  self.engine.connectSource(battery, self)  our applet will get called whenever the solidengine reports a change in the battery
(04:52:38 PM) Riddell: dataUpdated() will get called and that grabs the battery value and puts it into the SignalPlotter widget
(04:53:43 PM) Riddell: it looks like this
(04:54:13 PM) Riddell: as you can tell, the power of KDE is in its libraries and APIs, you can do a lot with a little code
(04:54:43 PM) Riddell: is the final code
(04:54:57 PM) Riddell: we're almost out of time
(04:55:01 PM) Riddell: any questions?
(04:55:21 PM) Riddell: RainCT rightly noted that Encoded= isn't needed in .desktop files any more, so that's one less line of code needed :)
(04:55:41 PM) Riddell: we have lots of plasmoid packaged in karmic now
(04:56:02 PM) Riddell: and you can get loads more from the Get New Stuff button in Plasma which downloads them from
(04:56:12 PM) Riddell: if you have an interesting applet written do put it on
(04:56:38 PM) Riddell: and if you find an interesting applet that a lot of people would be interested in, we probably want it packaged up into a .deb, which is pretty easy
(04:56:51 PM) Riddell: join us in #kubuntu-devel if you want to help or ask developer questions
(04:57:27 PM) Riddell: or #plasma for more detailed plasma knowledge
(04:57:33 PM) Riddell: these tutorials came from
(04:57:43 PM) Riddell:
(04:57:59 PM) Riddell: you can find loads of useful information on techbase (and if it's not there, it's a wiki so edit!)
(04:58:29 PM) Riddell: 21:56 < keffie_jayx_> QUESTION: is there a guide for packaging these plasmoids to keep in a PPA or something?
(04:58:42 PM) Riddell: there's the normal packaging guide on the ubuntu wiki
(04:58:55 PM) Riddell: for examples of Python Plasmoid packaging you can look at plasma-widget-facebook say in karmic
(04:59:22 PM) agateau: an interesting alternative distribution channel is kde-look,
(04:59:22 PM) Riddell: as agateau said you can upload it to so others can download it with Get New Stuff
(04:59:27 PM) Riddell: :)
(04:59:48 PM) Riddell: and if you want the package in the main Ubuntu archive put it on Revu and ping us on #kubuntu-devel to review it
(05:00:16 PM) Riddell: time up, anything to add agateau?
(05:00:37 PM) agateau: no, except that we are waiting for your plasmoids!
(05:01:17 PM) Riddell: thanks for coming everyone

MeetingLogs/devweek0909/PythonPlasmoids (last edited 2009-08-31 21:03:21 by pool-71-182-107-66)