PythonPlasmoids
Revision 4 as of 2009-08-31 21:03:21
Clear message
Dev Week -- Fun with Python Plasmoids -- agateau and Riddell -- Mon Aug 31st, 2009
UTC
(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: http://kde.org/announcements/4.2/screenshots/plasma-other-widgets.png (04:07:45 PM) agateau: http://kde.org/announcements/4.3/screenshots/desktop.png (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/main.py (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: X-KDE-PluginInfo-Email=simon@simonzone.com (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=http://plasma.kde.org/ (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: http://people.canonical.com/~jriddell/plasma-python/hello-python/metadata.desktop (04:16:32 PM) Riddell: so if you were following closely, you'll have worked out that code/main.py will be where the real code is (04:17:05 PM) Riddell: cd contents/code and emacs code.py (04:17:13 PM) Riddell: we all use emacs don't we? :) (04:17:36 PM) Riddell: sorry emacs main.py (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: painter.save() (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 http://people.canonical.com/~jriddell/plasma-python/hello-python/contents/code/main.py (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 hello-python.zip (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 http://people.canonical.com/~jriddell/plasma-python/hello-python.png (04:26:47 PM) Riddell: you can get the zip file from http://people.canonical.com/~jriddell/plasma-python/hello-python.zip 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: http://people.canonical.com/~agateau/udw/powerdevil.png (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 main.py (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 ../hello-widget.zip . (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 ../hello-widget.zip (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: http://api.kde.org/4.2-api/kdelibs-apidocs/plasma/html/annotated.html (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 http://api.kde.org/pykde-4.2-api/plasma/index.html (04:46:33 PM) Riddell: and you can always use the C++ API docs and convert them easily enough http://api.kde.org/4.x-api/kdelibs-apidocs/plasma/html/index.html (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 http://people.canonical.com/~jriddell/plasma-python/powerchart/contents/code/main.py (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 http://people.canonical.com/~jriddell/plasma-python/powerchart.png (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: http://people.canonical.com/~jriddell/plasma-python/powerchart.zip 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 kde-look.org (04:56:12 PM) Riddell: if you have an interesting applet written do put it on kde-look.org (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 techbase.kde.org (04:57:43 PM) Riddell: http://techbase.kde.org/Development/Tutorials/Plasma (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 kde-look.org 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