Monday, June 15, 2009

python, javascript or web?

While going through bug reports on bugs.kde.org, I had to install a Plasmoid over the internet using the Add Widgets dialog. It all worked pretty nicely (aside from the usual larger-than-good delay from kbuildsycoca4; I really need to find something to do about that ...), and soon I had a new widget. I dragged it to my desktop and got the "couldn't create a python scriptengine" error. Whoops! My PyKDE is currently not in a good state and I haven't had a chance to fix it yet, so no Python Plasmoids for me at the moment. :(

What was odd, though, was that it said in the description in Add Widgets that it was a JavaScript Tetris game. What would Python be needed for to run JavaScript? So I looked ...


# -*- coding: utf-8 -*-
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyKDE4.plasma import Plasma
from PyKDE4 import plasmascript
from PyKDE4.kdecore import KUrl

class jstetrisApplet(plasmascript.Applet):
def __init__(self,parent,args=None):
plasmascript.Applet.__init__(self,parent)

def init(self):
self.setHasConfigurationInterface(False)

self.theme = Plasma.Svg(self)
self.theme.setImagePath("widgets/background")
self.setBackgroundHints(Plasma.Applet.DefaultBackground)
self.setAspectRatioMode(Plasma.IgnoreAspectRatio)

self.layout = QGraphicsLinearLayout(Qt.Horizontal, self.applet)
webView = Plasma.WebView(self.applet)
webView.setUrl(KUrl("~/.kde/share/apps/plasma/plasmoids/jstetris/contents/jstet.html"))
self.layout.addItem(webView)
self.setLayout(self.layout)
self.resize(340,350)

def CreateApplet(parent):
return jstetrisApplet(parent)


A-ha! So it's creating a web viewer and loading the contents, all implemented in Python.

Unfortunately there are two errors there: first, calling resize there will not have the effect desired and second, there's a literal path to the jstet.html file. I blame myself for this because the scripting is still under-documented.

As penance, I re-wrote it in JavaScript:


plasmoid.hasConfigurationInterface = false
plasmoid.apectRatioMode = IgnoreAspectRatio

layout = new LinearLayout(plasmoid)
webView = new WebView()
webView.url = Url(plasmoid.file("scripts", "jstet.html"))
layout.addItem(webView)


In the metadata.desktop file I put:

X-Plasma-DefautSize=340,350


Both problems are fixed. The solution to the file path was to ask the plasmoid for the file from the package: plasmoid.file("scripts", "jstet.html"). This meant also moving the html (and JavaScript) files to the contents/code/ area of the package. Now there's no assumptions about where the package is installed to!

With JavaScript it's guaranteed to work everywhere (no additional dependencies) and it's even less typing.

Then it dawned on me: this is a web Plasmoid! So I deleted the JavaScript file I'd just made and changed the metadata.desktop file so it said:

X-Plasma-API=webkit
X-Plasma-MainScript=jstet.html


Note that the X-Plasma-MainScript entry only works with web plasmoids in 4.3, though it works with JavaScript, Ruby and Python Plasmoids in 4.2; previous to 4.3, you need to call your main html file main.html (which is still the default in 4.3 of course).

The only downside to this over the JavaScript Plasmoid approach above is that the WebKit ScriptEngine is in kdebase/workspace while the JavaScript ScriptEngine is in kdebase/runtime. I wonder if I should move the WebKit ScriptEngine over to runtime/ as well? Hm.. maybe something for 4.4. In any case, it means writing zero Plasma specific code.

Anyways, what's the result? All three approaches gives us this:



I can't take any credit for the actual hard work here, the JavaScript, was done by one Cezary Tomczak and the original Python plasmoid by Tomatz on kde-look.org. :)

13 comments:

Onestone said...

Regarding "couldn't create a python scriptengine", it's not just you... I'm getting the same error on KDE 4.2.90 (worked fine on KDE 4.2.85). Others report it too, e.g. here: http://code.google.com/p/gmail-plasmoid/issues/detail?id=11

behavedave said...

Could you point out a QT-Script tutorial, there doesn't seem to be any anywhere to be found, I can find the API's but they seem to be quite confusing alone (just loading an image from disk and putting it on the canvas doesn't seem possible), I even tried using QT creator but that only does C++ (and python with a converting script).

lxj said...

Wait, can it actually point to a page in the web? Then one can re-write these plasmoids in 3 lines?

http://hamberg.no/erlend/2009/05/05/google-calendar-plasmoid/

http://labs.trolltech.com/blogs/2009/03/08/creating-a-google-chat-client-in-15-minutes/

(Of course authors of these plasmoids also added some additional features later on, like remembering the password. But still...)

lxj said...

Also looking at this line:

self.setHasConfigurationInterface(False)

-- I think why there is a configure button and menu item on every plasmoid, even it doesn't have a configure dialog?

Aaron J. Seigo said...

@Onestone: in my case, at least, it's simply because i don't have PyKDE installed in working order

@behavedave: you mean for writing Plasmoids? no, there isn't a complete tutorial at the moment.

@lxj: yes, it can point to any page on the web, and yes, you could rewrite those plasmoids in very little (and platform independent) code.

as for the config button, that's to provide universal access to shotcut configuration. any widget can have a shortcut assigned.

it is still useful for us to know when the applet _itself_ does or doesn't have configuration.

LXj said...

This is very neat! Oh, and by the way:

calling resize there will not have the effect desired

Funny thing, the same could be said about the standard web browser applet (at least in 4.2). That's why I'm so interested in this

lxj said...

Hmm, I tried putting

X-Plasma-MainScript=http://gmail.com

...and got error opening script

as for the config button, that's to provide universal access to shotcut configuration. any widget can have a shortcut assigned.

Seems like it doesn't work for non-plasma widgets on 4.2

Aaron J. Seigo said...

ah, you mean putting the url directly in the .desktop file! no, that probably doesn't work, even in 4.3. the url would need to go into the included html file.

as for the config button not working on non-Plasmoid widgets, that may depend on how the script engine works; however, at least in 4.3 (would have to check 4.2's code base), there is a shortcuts page added even to ScriptEngine widgets and the shortcut does send the activated signal.

bumlare said...

@behavedave
I don't know if this qualifies as a tutorial:
http://techbase.kde.org/Development/Tutorials/Plasma#Plasma_Programming_with_QtScript

lxj said...

Just installed KDE SVN, clicked configure button on my Google Reader Google Gadget -- nothing happened. Clicked the same button on RamMeter SuperKaramba widget -- again nothing happened. Should I report to b.k.o?

Also web browser plasmoid now resizes. Wheee!

lxj said...

By the way, the reason why the author of that plasmoid did that, is probably because there are tutorials for Python, JS, etc plasmoids on TechBase, but no tutorial for web plasmoids. So he probably didn't know about such possibility :)

lxj said...

Tried with Mac OS widget -- it actually worked, configure dialog showed up

Znurre said...

It seems as if the plasmoid background is drawn automatically this way, and there is no way to disable it afaik.

I tried

setBackgroundHints( 0 )
setBackgroundHints( Plasma::Applet.NoBackground )
setBackgroundHints( NoBackground )

in one of my Ruby plasmoids using the X-Plasma-MainScript entry in the desktop file.

Is there any way to solve this?
Maybe another X-Plasma-* entry in the desktop file?
I searched the techbase but didn't find anything.