Difference between revisions of "Paths/Developer/Creating plasmoids with scripts"

Jump to: navigation, search
(Python scriptengine tutorial)
(Fixed formatting)
Line 3: Line 3:
 
http://chani.wordpress.com/2008/12/29/adventures-in-plasmaland-part-1/
 
http://chani.wordpress.com/2008/12/29/adventures-in-plasmaland-part-1/
  
Tutorial 1:
+
==Introduction==
  
TOC:
+
The Python Hello World.
Layout
+
Note: This may need work. I haven't tested the script and wrote/translated some code on the fly for this tutorial. There may very well be typos. Sorry.
Hello World Applet
+
Installation via Plasmapkg
+
  
  
 +
==Layout==
 +
Each scripted plasmoid shares the same layout.
 +
The base folder name is, your applet's name, like "hello world"
  
Python hello world.
+
Base
 
+
Layout:
+
  Each scripted plasmoid shares the same layout. The base folder name is, your applet's name, like "hello world"
+
Base
+
 
   metadata.desktop
 
   metadata.desktop
 
  Contents
 
  Contents
Line 22: Line 19:
 
   Ui
 
   Ui
  
 +
==metadata.desktop==
 
The base folder contains a metadata.desktop, which should look a little something like:
 
The base folder contains a metadata.desktop, which should look a little something like:
  
[Desktop Entry]
+
[Desktop Entry]
Encoding=UTF-8
+
Encoding=UTF-8
Name=Hello World
+
Name=Hello World
Type=Service
+
Type=Service
ServiceTypes=Plasma/Applet
+
ServiceTypes=Plasma/Applet
X-Plasma-API=python
+
X-Plasma-API=python
 
+
X-KDE-PluginInfo-Author=Matthew Adams
X-KDE-PluginInfo-Author=Matthew Adams
+
X-KDE-PluginInfo-Email=
X-KDE-PluginInfo-Email=
+
X-KDE-PluginInfo-Name=myHelloWorld
X-KDE-PluginInfo-Name=myHelloWorld
+
X-KDE-PluginInfo-Version=1.0
X-KDE-PluginInfo-Version=1.0
+
X-KDE-PluginInfo-Website=http://plasma.kde.org/
X-KDE-PluginInfo-Website=http://plasma.kde.org/
+
X-KDE-PluginInfo-Category=Examples
X-KDE-PluginInfo-Category=Examples
+
X -KDE-PluginInfo-Depends=
X-KDE-PluginInfo-Depends=
+
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-License=GPL
+
X-KDE-PluginInfo-EnabledByDefault=true
X-KDE-PluginInfo-EnabledByDefault=true
+
X-Ubuntu-Gettext-Domain=desktop_kdebase-workspace
 
+
X-KDE-PluginInfo-EnabledByDefault=true
X-Ubuntu-Gettext-Domain=desktop_kdebase-workspace
+
 
+
X-KDE-PluginInfo-EnabledByDefault=true
+
  
 
In Base/contents/code you will have your main script file, named "main.py"
 
In Base/contents/code you will have your main script file, named "main.py"
 
This is your main script file. The main.py should have a function called "def CreateApplet(parent):" that returns an object that inherits plasma.Applet. in order to be able to inherit plasma.Applet you will need to include a couple specific headers. Here's the helloworld script:
 
This is your main script file. The main.py should have a function called "def CreateApplet(parent):" that returns an object that inherits plasma.Applet. in order to be able to inherit plasma.Applet you will need to include a couple specific headers. Here's the helloworld script:
 
+
==The Script==
 
(I haven't tested this script, just hacked up an already existing one on the fly, it might have typos, and as a note, there is a huge difference between plasma.Applet and Plasma.Applet.)
 
(I haven't tested this script, just hacked up an already existing one on the fly, it might have typos, and as a note, there is a huge difference between plasma.Applet and Plasma.Applet.)
 +
<source lang=python>
 +
# Import all the headers for Qt and KDE
 +
from PyQt4.QtCore import *
 +
from PyQt4.QtGui import *
 +
from PyKDE4.kdecore import *
 +
from PyKDE4.kdeui import *
 +
from PyKDE4.plasma import Plasma
 +
import plasma
  
# Import all the headers for Qt and KDE
+
class HelloWorld(plasma.Applet):
from PyQt4.QtCore import *
+
  def __init__(self, parent, args=None):
from PyQt4.QtGui import *
+
    plasma.Applet.__init__(self, parent)
from PyKDE4.kdecore import *
+
  def init(self):
from PyKDE4.kdeui import *
+
    self.text = "Hello World"
from PyKDE4.plasma import Plasma
+
    self.svg = Plasma::Svg.new(@top.applet())
import plasma
+
    self.svg.imagePath = 'widgets/background'
 
+
  # Yes the code for drawing the text directly on to the applet is fairly large
class HelloWorld(plasma.Applet):
+
  # and ugly. It can be done other ways however, add a layout to the applet,
  def __init__(self, parent, args=None):
+
  # then a text label to the layout, then draw the text onto the text label
    plasma.Applet.__init__(self, parent)
+
  # Although I've never tried that method. This entire method was borrowed
  def init(self):
+
  # From one of the clock applets.
    self.text = "Hello World"
+
  def paintInterface(self):
    self.svg = Plasma::Svg.new(@top.applet())
+
      p.pen = Plasma.Theme.defaultTheme.color(Plasma.Theme.TextColor)
    self.svg.imagePath = 'widgets/background'
+
      plainFont = KDE.GlobalSettings.generalFont
  def paintInterface(self):
+
      plainFont.pointSizeF = [rect.height, KDE::GlobalSettings.smallestReadableFont.pointSize].max
    p.pen = Plasma.Theme.defaultTheme.color(Plasma.Theme.TextColor)
+
      preparePainter(p, rect,@plainFont, self.text)
    plainFont = KDE.GlobalSettings.generalFont
+
      p.drawText(QRectF.new(rect), self.text, QTextOption(QAlignCenter))
    plainFont.pointSizeF = [rect.height, KDE::GlobalSettings.smallestReadableFont.pointSize].max
+
      self.svg.resize(rect.left+rect.right+1, rect.top+rect.bottom+1);
    preparePainter(p, rect,@plainFont, self.text)
+
      self.svg.paint(p, QRectF(rect), "widgets/background")
    p.drawText(QRectF.new(rect), self.text, QTextOption(QAlignCenter))
+
    self.svg.resize(rect.left+rect.right+1, rect.top+rect.bottom+1);
+
      resize(rect.left+rect.right+1, rect.top+rect.bottom+1)
    self.svg.paint(p, QRectF(rect), "widgets/background")
+
    def preparePainter(p, rect, font, text)
 
+
          tmpRect = QRect
    resize(rect.left+rect.right+1, rect.top+rect.bottom+1)
+
          tmpFont = font
  def preparePainter(p, rect, font, text)
+
          # Starting with the given font, decrease its size until it'll fit in the
        tmpRect = QRect
+
          # given rect allowing wrapping where possible. Thx clock applet!
        tmpFont = font
+
  do:
        # Starting with the given font, decrease its size until it'll fit in the
+
            p.font = tmpFont
        # given rect allowing wrapping where possible
+
            tmpFont.pointSize = [KDE/GlobolSettings.smallestReadableFont.pointSize, tmpFont.pointSize - 1].max
do:
+
            tmpRect = p.boundingRect(rect, QTextWordWrap, text)
          p.font = tmpFont
+
          while tmpFont.pointSize > KDE::GlobalSettings.smallestReadableFont.pointSize && (tmpRect.width > rect.width || tmpRect.height > rect.height)
          tmpFont.pointSize = [KDE/GlobolSettings.smallestReadableFont.pointSize, tmpFont.pointSize - 1].max
+
            return tmpRect
          tmpRect = p.boundingRect(rect, QTextWordWrap, text)
+
         
        while tmpFont.pointSize > KDE::GlobalSettings.smallestReadableFont.pointSize && (tmpRect.width > rect.width || tmpRect.height > rect.height)
+
def CreateApplet(parent):
 
+
  return HelloWorld(self)
            return tmpRect
+
</source>
         
+
==Explaination==
def CreateApplet(parent):
+
The SVG, The Font, and the Applet have to be made. The SVG is basically the Plasma Theme system. The font is resized to fit inside the bounding rect of the applet (Which can change when the user resizes it), Then the text is drawn to the screen using the resized font. Fairly simple.
  return HelloWorld(self)
+
 
+
Explaination:
+
The SVG, The Font, and the Applet have to be made. The SVG is basically the Plasma Theme system. The font is resized to fit inside the bounding rect of the applet (Which can change when the user resizes it), Then the text is drawn to the screen using the resized font. Fairly simple.
+
  
 
CreateApplet gets called at startup, and returns the applet we made. It's paintinterface button is called every so often to have the interface painted (text draw to the screen), first __init__() get's called, but then the library calls "init(self)" on the object, which is where all the real setup happens.
 
CreateApplet gets called at startup, and returns the applet we made. It's paintinterface button is called every so often to have the interface painted (text draw to the screen), first __init__() get's called, but then the library calls "init(self)" on the object, which is where all the real setup happens.
  
  
Installation:
+
==Installation==
 
   Once you have it all setup, simply run:
 
   Once you have it all setup, simply run:
 
   cd /path/to/BASE/
 
   cd /path/to/BASE/
Line 103: Line 102:
 
   plasmapkg -i ../HelloWorld.plasmoid
 
   plasmapkg -i ../HelloWorld.plasmoid
  
Removal:
+
==Removal==
 
   On old kde 4.1.X plasmapkg didn't work with plasmapkg -r ../HelloWorld.plasmoid
 
   On old kde 4.1.X plasmapkg didn't work with plasmapkg -r ../HelloWorld.plasmoid
 
   It does in 4.2X - use plasmapkg -r ../HelloWorld.plasmoid in 4.2X
 
   It does in 4.2X - use plasmapkg -r ../HelloWorld.plasmoid in 4.2X
 
 
   In 4.1.X do rm -r ~/.kde/share/apps/plasma/plasmoids/HelloWorld to remove
 
   In 4.1.X do rm -r ~/.kde/share/apps/plasma/plasmoids/HelloWorld to remove
  
 
      
 
      
 +
==End Notes==
 +
Once you complete a useful or fun plasmoids, you can put it on KDE-Look.org under the scripted plasmoids section, and have it show up in Get Hot New Stuff on peoples computers without them ever opening a web browser.
  
Note: Once you complete a useful or fun plasmoids, you can put it on KDE-Look.org under the scripted plasmoids section, and have it show up in Get Hot New Stuff on peoples computers without them ever opening a web browser.
+
The differences between Plasma, KDE, and Qt are all very subtle. It is possible and advised to use Qt Designer for the creation of your gui's, and tying them in to your Plasmoid. You can use the output from Qt Designer directly after passing it through pyuic4 without any changes to the output from the .ui file - which means you can design applets so that the gui can be redone and replaced in Qt Designer without touching a single line of code. How is that bad for artists? That's a lesson for another day however. Peace.

Revision as of 01:21, 31 December 2008

Plasma Chani's advantures in PlasmaLand: http://chani.wordpress.com/2008/12/29/adventures-in-plasmaland-part-1/

Contents

Introduction

The Python Hello World. Note: This may need work. I haven't tested the script and wrote/translated some code on the fly for this tutorial. There may very well be typos. Sorry.


Layout

Each scripted plasmoid shares the same layout. The base folder name is, your applet's name, like "hello world"

Base
  metadata.desktop
Contents
 Code
 Ui

metadata.desktop

The base folder contains a metadata.desktop, which should look a little something like:

[Desktop Entry]
Encoding=UTF-8
Name=Hello World
Type=Service
ServiceTypes=Plasma/Applet
X-Plasma-API=python
X-KDE-PluginInfo-Author=Matthew Adams
X-KDE-PluginInfo-Email=
X-KDE-PluginInfo-Name=myHelloWorld
X-KDE-PluginInfo-Version=1.0
X-KDE-PluginInfo-Website=http://plasma.kde.org/
X-KDE-PluginInfo-Category=Examples
X -KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
X-Ubuntu-Gettext-Domain=desktop_kdebase-workspace
X-KDE-PluginInfo-EnabledByDefault=true

In Base/contents/code you will have your main script file, named "main.py" This is your main script file. The main.py should have a function called "def CreateApplet(parent):" that returns an object that inherits plasma.Applet. in order to be able to inherit plasma.Applet you will need to include a couple specific headers. Here's the helloworld script:

The Script

(I haven't tested this script, just hacked up an already existing one on the fly, it might have typos, and as a note, there is a huge difference between plasma.Applet and Plasma.Applet.)

 # Import all the headers for Qt and KDE
 from PyQt4.QtCore import *
 from PyQt4.QtGui import *
 from PyKDE4.kdecore import *
 from PyKDE4.kdeui import *
 from PyKDE4.plasma import Plasma
 import plasma
 
 class HelloWorld(plasma.Applet):
   def __init__(self, parent, args=None):
     plasma.Applet.__init__(self, parent)
   def init(self):
     self.text = "Hello World"
     self.svg = Plasma::Svg.new(@top.applet())
     self.svg.imagePath = 'widgets/background'
   # Yes the code for drawing the text directly on to the applet is fairly large
   # and ugly. It can be done other ways however, add a layout to the applet,
   # then a text label to the layout, then draw the text onto the text label 
   # Although I've never tried that method. This entire method was borrowed
   # From one of the clock applets. 
   def paintInterface(self):
      p.pen = Plasma.Theme.defaultTheme.color(Plasma.Theme.TextColor)
      plainFont = KDE.GlobalSettings.generalFont
      plainFont.pointSizeF = [rect.height,  KDE::GlobalSettings.smallestReadableFont.pointSize].max
      preparePainter(p, rect,@plainFont, self.text)
      p.drawText(QRectF.new(rect), self.text, QTextOption(QAlignCenter))
      self.svg.resize(rect.left+rect.right+1, rect.top+rect.bottom+1);
      self.svg.paint(p, QRectF(rect), "widgets/background")
 
      resize(rect.left+rect.right+1, rect.top+rect.bottom+1)
    def preparePainter(p, rect, font, text)
          tmpRect = QRect
          tmpFont = font
          # Starting with the given font, decrease its size until it'll fit in  the
          # given rect allowing wrapping where possible. Thx clock applet!
 	  do:
            p.font = tmpFont
            tmpFont.pointSize =  [KDE/GlobolSettings.smallestReadableFont.pointSize, tmpFont.pointSize - 1].max
            tmpRect = p.boundingRect(rect, QTextWordWrap, text)
          while tmpFont.pointSize >  KDE::GlobalSettings.smallestReadableFont.pointSize && (tmpRect.width >  rect.width || tmpRect.height > rect.height)
             return tmpRect
 
 def CreateApplet(parent):
   return HelloWorld(self)

Explaination

The SVG, The Font, and the Applet have to be made. The SVG is basically the Plasma Theme system. The font is resized to fit inside the bounding rect of the applet (Which can change when the user resizes it), Then the text is drawn to the screen using the resized font. Fairly simple.

CreateApplet gets called at startup, and returns the applet we made. It's paintinterface button is called every so often to have the interface painted (text draw to the screen), first __init__() get's called, but then the library calls "init(self)" on the object, which is where all the real setup happens.


Installation

 Once you have it all setup, simply run:
 cd /path/to/BASE/
 zip -r ../HelloWorld.plasmoid *
 plasmapkg -i ../HelloWorld.plasmoid

Removal

 On old kde 4.1.X plasmapkg didn't work with plasmapkg -r ../HelloWorld.plasmoid
 It does in 4.2X - use plasmapkg -r ../HelloWorld.plasmoid in 4.2X
 In 4.1.X do rm -r ~/.kde/share/apps/plasma/plasmoids/HelloWorld to remove


End Notes

Once you complete a useful or fun plasmoids, you can put it on KDE-Look.org under the scripted plasmoids section, and have it show up in Get Hot New Stuff on peoples computers without them ever opening a web browser.

The differences between Plasma, KDE, and Qt are all very subtle. It is possible and advised to use Qt Designer for the creation of your gui's, and tying them in to your Plasmoid. You can use the output from Qt Designer directly after passing it through pyuic4 without any changes to the output from the .ui file - which means you can design applets so that the gui can be redone and replaced in Qt Designer without touching a single line of code. How is that bad for artists? That's a lesson for another day however. Peace.


KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V.Legal