Difference between revisions of "Development/Tutorials/Plasma/Ruby/SimplePasteApplet"

Jump to: navigation, search
(Fix links)
m (Text replace - "</code>" to "</syntaxhighlight>")
 
(19 intermediate revisions by 3 users not shown)
Line 1: Line 1:
Warning: This tutorial has not yet been completely tested and might contain incorrect information or examples.
 
 
 
== Abstract ==
 
== Abstract ==
  
Line 9: Line 7:
 
Before you get started you need to make sure to have the following installed on your computer.
 
Before you get started you need to make sure to have the following installed on your computer.
  
* KDE 4.2
+
* KDE 4.2 or later
 
* Ruby 1.8
 
* Ruby 1.8
* KDE 4.2 Ruby bindings
+
* KDE Ruby bindings and Plasma scriptengine
  
 
These packages can usually be installed through your distributions package manager.
 
These packages can usually be installed through your distributions package manager.
Line 28: Line 26:
 
A minimal <tt>metadata.desktop</tt> file looks like this:
 
A minimal <tt>metadata.desktop</tt> file looks like this:
  
<code ini>
+
<syntaxhighlight lang="ini">
 
[Desktop Entry]
 
[Desktop Entry]
 
Name=Simple Ruby applet
 
Name=Simple Ruby applet
Line 48: Line 46:
 
X-KDE-PluginInfo-License=GPL
 
X-KDE-PluginInfo-License=GPL
 
X-KDE-PluginInfo-EnabledByDefault=true
 
X-KDE-PluginInfo-EnabledByDefault=true
</code>
+
</syntaxhighlight>
  
 
== Code ==
 
== Code ==
Line 56: Line 54:
 
Start your code file with requiring 'plasma_applet' and opening a module. A minimal Ruby Plasma applet looks like this:
 
Start your code file with requiring 'plasma_applet' and opening a module. A minimal Ruby Plasma applet looks like this:
  
<code ruby>
+
<syntaxhighlight lang="ruby">
 
require 'plasma_applet'
 
require 'plasma_applet'
  
Line 70: Line 68:
 
   end
 
   end
 
end
 
end
</code>
+
</syntaxhighlight>
  
 
The module name must match the name you specify in metadata.desktop on the <tt>X-KDE-PluginInfo-Name</tt> line. The name <tt>ruby-test</tt> translates to a module name of <tt>RubyTest</tt>.
 
The module name must match the name you specify in metadata.desktop on the <tt>X-KDE-PluginInfo-Name</tt> line. The name <tt>ruby-test</tt> translates to a module name of <tt>RubyTest</tt>.
Line 76: Line 74:
 
The only line in the <tt>init</tt> method now is <tt>set_minimum_size</tt>. This, as the name suggests, sets the minimum size for the applet.
 
The only line in the <tt>init</tt> method now is <tt>set_minimum_size</tt>. This, as the name suggests, sets the minimum size for the applet.
  
To run your applet, you first need to install it. This is where <tt>plasmapkg</tt> comes in. It's a small tool which installs and upgrades Plasma packages. To put your code in a package, create a package structure as described in the above section. Outsize the package folder run <tt>plasmapkg -i <package folder name></tt>. <tt>Plasmapkg</tt> will now install your applet.
+
To run your applet, you have two options. You can install it first, and then run it. Or, if you're running KDE 4.3 or later, just run it.
  
<code bash>
+
== Installing your appliet ==
 +
 
 +
This is where <tt>plasmapkg</tt> comes in. It's a small tool which installs and upgrades Plasma packages. To put your code in a package, create a package structure as described in the above section. Outside the package folder run <tt>plasmapkg -i <package folder name></tt>, <tt>plasmapkg</tt> will now install your applet.
 +
 
 +
<syntaxhighlight lang="bash">
 
mkdir ruby-test-applet
 
mkdir ruby-test-applet
 
cd ruby-test-applet
 
cd ruby-test-applet
Line 89: Line 91:
 
cd ../../..
 
cd ../../..
 
plasmapkg -i ruby-test-applet
 
plasmapkg -i ruby-test-applet
</code>
+
</syntaxhighlight>
  
Now that your applet is installed, you can view it. You can do this with a tool called <tt>plasmoidviewer</tt>. As argument it takes the name of your plasma applet specified with <tt>X-KDE-PluginInfo-Name</tt> in the <tt>metadata.desktop</tt> file. Launch <tt>plasmoidviewer</tt> and see your still empty Plasma applet running.
+
<tt>plasmapkg</tt> can install and upgrade Plasma packages. Since you've now installed your applet, you need to upgrade it after making changes. This isn't much different then installing, just use the <tt>-u</tt> commandline switch instead of <tt>-i</tt>.
  
<code bash>
+
== Running your applet ==
 +
 
 +
You can run your applet using a tool called <tt>plasmoidviewer</tt>.
 +
 
 +
=== KDE 4.2 ===
 +
 
 +
In KDE 4.2 <tt>plasmoidviewer</tt> takes the name of an installed applet as a parameter.  The name of your applet is specified with the <tt>X-KDE-PluginInfo-Name</tt> line in your <tt>metadata.desktop</tt> file. You should be able to view your applet after installing it.
 +
 
 +
<syntaxhighlight lang="bash">
 
plasmoidviewer ruby-test
 
plasmoidviewer ruby-test
</code>
+
</syntaxhighlight>
  
<tt>plasmapkg</tt> can install and upgrade Plasma packages. Since you've now installed your applet, you need to upgrade it after making changes. This isn't much different then installing, just use the <tt>-u</tt> commandline switch instead of <tt>-i</tt>.
+
=== KDE 4.3 ===
 +
 
 +
In KDE 4.3 plasmoidviewer still accepts the name of an installed applet as a parameter. But it can also run without a parameter. It will then try to run a plasmoid from the current directory. In order for this to work, the current directory should have the <tt>metadata.desktop</tt> file, the contents folder and the name of the directory should exactly match the name of the applet as specified in metadata.desktop.
 +
 
 +
<syntaxhighlight lang="bash">
 +
plasmoidviewer
 +
</syntaxhighlight>
  
 
== A label on an applet ==
 
== A label on an applet ==
Line 107: Line 123:
 
When putting a <tt>Plasma::Label</tt> on an applet in a <tt>GraphicsLinearLayout</tt>, you'll get the following code:
 
When putting a <tt>Plasma::Label</tt> on an applet in a <tt>GraphicsLinearLayout</tt>, you'll get the following code:
  
<code ruby>
+
<syntaxhighlight lang="ruby">
 
require 'plasma_applet'
 
require 'plasma_applet'
  
Line 114: Line 130:
 
     def initialize parent
 
     def initialize parent
 
       super parent
 
       super parent
      @parent = parent
 
 
     end
 
     end
  
Line 120: Line 135:
 
       set_minimum_size 150, 150
 
       set_minimum_size 150, 150
  
       label = Plasma::Label.new @parent.applet
+
       label = Plasma::Label.new self
 
       label.text = 'This is a label on a plasmoid, hello Plasma!'
 
       label.text = 'This is a label on a plasmoid, hello Plasma!'
  
       layout = Qt::GraphicsLinearLayout.new @parent.applet
+
       layout = Qt::GraphicsLinearLayout.new self
       @parent.applet.layout = layout
+
       self.layout = layout
 
       layout.add_item label
 
       layout.add_item label
 
     end
 
     end
 
   end
 
   end
 
end
 
end
</code>
+
</syntaxhighlight>
  
To place widgets on the applet, we need the applet's parent. This parent has a method called <tt>applet</tt>, which gives us a reference to the 'real' applet. To get to this applet, we save the parent in a instance variable. In the <tt>init</tt> method we create a <tt>Plasma::Label</tt> and assign it a text. Next we create a <tt>GraphicsLinearLayout</tt>, assign it to the applet and put our label on it.
+
In the <tt>init</tt> method we create a <tt>Plasma::Label</tt> and assign it a text. The first argument to the constructor of <tt>Plasma::Label</tt> (the <tt>new</tt>) is the parent of the label, in this case our applet. Next we create a <tt>GraphicsLinearLayout</tt>, assign it to the applet and put our label on it.
  
 
{{tip|In Ruby, instance variables always begin with an '@' character. All variables without an '@' are local variables. Variables with two @ signs are class (a.k.a. static) variables.}}
 
{{tip|In Ruby, instance variables always begin with an '@' character. All variables without an '@' are local variables. Variables with two @ signs are class (a.k.a. static) variables.}}
 +
 +
{{tip|The Ruby keyword <tt>self</tt> is a reference to the current instance of the class you're in. You can compare it with the <tt>this</tt> keyword in other languages like C++ and Java.}}
  
 
To view your applet, run <tt>plasmapkg -u <folder name></tt> and <tt>plasmoidviewer <plasmoid name></tt>.
 
To view your applet, run <tt>plasmapkg -u <folder name></tt> and <tt>plasmoidviewer <plasmoid name></tt>.
  
<code bash>
+
<syntaxhighlight lang="bash">
 
plasmapkg -u ruby-test-applet
 
plasmapkg -u ruby-test-applet
 
plasmoidviewer ruby-test
 
plasmoidviewer ruby-test
</code>
+
</syntaxhighlight>
  
 
This will show you a nice and simple Hello World in Plasma.  
 
This will show you a nice and simple Hello World in Plasma.  
Line 147: Line 164:
  
 
Let's continue by adding a line edit and a button with some functionality.
 
Let's continue by adding a line edit and a button with some functionality.
 
Before that, let's do a small clean up. In the previous example we used <tt>@parent.applet</tt> a lot. We can clean this up by defining a method called <tt>applet</tt> which returns <tt>@parent.applet</tt>.
 
 
<code ruby>
 
def applet
 
  @parent.applet
 
end
 
</code>
 
 
{{note|With Ruby, it's not required to write the <tt>return</tt> keyword. This can be a bit confusing for newcomers. But it can make a method very clear, I think the <tt>applet</tt> method is a good example of such a case. You are of course, free to put a <tt>return</tt> in front of the single line in the method. }}
 
  
 
To add a line edit widget we can use the <tt>Plasma::LineEdit</tt> class. This class is a basic <tt>KLineEdit</tt> (a text field with one line) themed for Plasma. To add it to our applet, we do the same as with the label. But since we want the line edit to be empty, we don't set a text.
 
To add a line edit widget we can use the <tt>Plasma::LineEdit</tt> class. This class is a basic <tt>KLineEdit</tt> (a text field with one line) themed for Plasma. To add it to our applet, we do the same as with the label. But since we want the line edit to be empty, we don't set a text.
Line 164: Line 171:
 
With a line edit and button in place, we should let the button do something when it's clicked. Qt, the library on which KDE is based, uses a mechanism called 'signals and slots'. You could compare it to action or event handlers in other languages or frameworks. Normally, one would connect a certain signal (event) to a certain slot (event handler method). Since we're using Ruby, we can't only do that, we can connect a signal to a code block. The syntax for this is easy:
 
With a line edit and button in place, we should let the button do something when it's clicked. Qt, the library on which KDE is based, uses a mechanism called 'signals and slots'. You could compare it to action or event handlers in other languages or frameworks. Normally, one would connect a certain signal (event) to a certain slot (event handler method). Since we're using Ruby, we can't only do that, we can connect a signal to a code block. The syntax for this is easy:
  
<code ruby>
+
<syntaxhighlight lang="ruby">
 
button.connect(SIGNAL(:clicked)) do
 
button.connect(SIGNAL(:clicked)) do
 
   # do something
 
   # do something
 
end
 
end
</code>
+
</syntaxhighlight>
  
 
Now, when the button gets clicked, the code in the block gets executed.
 
Now, when the button gets clicked, the code in the block gets executed.
Line 178: Line 185:
 
Putting it all together, we have to following code:
 
Putting it all together, we have to following code:
  
<code ruby>
+
<syntaxhighlight lang="ruby">
 
require 'plasma_applet'
 
require 'plasma_applet'
  
Line 185: Line 192:
 
     def initialize parent
 
     def initialize parent
 
       super parent
 
       super parent
      @parent = parent
 
    end
 
 
    def applet
 
      @parent.applet
 
 
     end
 
     end
  
Line 195: Line 197:
 
       set_minimum_size 150, 150
 
       set_minimum_size 150, 150
  
       layout = Qt::GraphicsLinearLayout.new Qt::Vertical, applet
+
       layout = Qt::GraphicsLinearLayout.new Qt::Vertical, self
       applet.layout = layout
+
       self.layout = layout
  
       label = Plasma::Label.new applet
+
       label = Plasma::Label.new self
 
       label.text = 'This plasmoid will copy the text you enter below to the clipboard.'
 
       label.text = 'This plasmoid will copy the text you enter below to the clipboard.'
 
       layout.add_item label
 
       layout.add_item label
  
       line_edit = Plasma::LineEdit.new applet
+
       line_edit = Plasma::LineEdit.new self
 
       layout.add_item line_edit
 
       layout.add_item line_edit
  
       button = Plasma::PushButton.new applet
+
       button = Plasma::PushButton.new self
 
       button.text = 'Copy to clipboard'
 
       button.text = 'Copy to clipboard'
 
       layout.add_item button
 
       layout.add_item button
Line 216: Line 218:
 
   end
 
   end
 
end
 
end
</code>
+
</syntaxhighlight>
  
== Where to go from here ==
+
== Reading API reference documentation ==
  
 
Now that you have this simple but working Ruby Plasma applet, you can expand it. You can start by trying out some of the other Plasma widgets available. The official [http://api.kde.org/4.x-api/kdelibs-apidocs/plasma/html/hierarchy.html Plasma API] is unfortunately written for C++. But with a little imagination and some logic you should be able to make use of it.
 
Now that you have this simple but working Ruby Plasma applet, you can expand it. You can start by trying out some of the other Plasma widgets available. The official [http://api.kde.org/4.x-api/kdelibs-apidocs/plasma/html/hierarchy.html Plasma API] is unfortunately written for C++. But with a little imagination and some logic you should be able to make use of it.
  
You could also try looking at some Ruby Plasma examples[4]. These are written a bit different then the example described above, but they should still be useful.
+
Still reading this tutorial? Let's take it step by step then.
 +
 
 +
Look through the Plasma API hierachy and find the LineEdit class. At the top of its own page is a listing of the available Signals. Duplicate the code for the button signal in your text editor:
 +
 
 +
<syntaxhighlight lang="ruby">
 +
button.connect(SIGNAL(:clicked)) do
 +
  Qt::Application.clipboard.text = line_edit.text
 +
end
 +
 
 +
button.connect(SIGNAL(:clicked)) do
 +
  Qt::Application.clipboard.text = line_edit.text
 +
end
 +
</syntaxhighlight>
 +
 
 +
And now reuse that code block to make your line edit variable also paste the typed content to the clipboard when the return key on the keyboard is being pressed. Save and run your code (in KDE 4.2 you must not forget to update manualy, in KDE 4.3 you can run 'Plasmoidviewer' when Konsole is pointing to the folder / directory of your Applet). My clipboard missed a few pastes but both the button and pressing return worked. Look a bit lower on the Class page for LineEdit: the C++ code to signal an action looks different then the Ruby signal you copied and the Ruby signal you composed yourself, but it does list in which KDE version the signal has become available.
 +
 
 +
Now you know how to let your Plasma Applet react to any signal and you know how to find all available signals in Plasma.
 +
 
 +
== Enabling Public Member Functions ==
 +
 
 +
The second list at the top of the lineEdit class page of the API reference documentation names all the Public Member Functions. These are the extra features which we can use for the line_edit class. A nice looking feature is the clear button, which can appear when some text is typed and when clicked with the mouse pointer clears the text, so the user of your widget can type something different. The page mentions two functions related to the clear button for C++ programmers. In Ruby however the functions are cleanly united by the Ruby Qt bindings. So remember you must drop both '''is''' and '''set''' from the function to make it a Ruby method. The class page also says that this function uses only a '''true''' or '''false''' boolean parameter, indicated on the class page by the word "'''bool'''". To enable the clear button feature we must insert the parameter true with following code:
 +
 
 +
<syntaxhighlight lang="ruby">
 +
line_edit.clear_button_shown = true
 +
</syntaxhighlight>
 +
 
 +
Notice that the Ruby Qt bindings allows us to use underscores which increases the readability of all methods for non-native English speakers. So "setClearButtonShown (bool show)" becomes either "clear_button_shown = true" or clear_button_shown = false". Also remember that when scrolling down the class page it states that this feature only works in Plasma version 4.3 or later. This means that on earlier versions your plasmoid application will suddenly not run at all and give an error. For optional features not available in earlier versions of Plasma we should always tell the applet not to run the code when it gives an error. So now we will place the line inside a rescue operation which does nothing but skip the code when it gives an error:
 +
 
 +
<syntaxhighlight lang="ruby">
 +
begin
 +
  line_edit.clear_button_shown = true
 +
rescue
 +
end
 +
</syntaxhighlight>
 +
 
 +
{{tip|Ruby exception handling allows you to do something else when a block of code gives an error or just skip the code block completely. It works like this:
 +
<syntaxhighlight lang="ruby">
 +
begin
 +
  # the piece of code which may error
 +
  # when the program is used
 +
rescue
 +
  # the optional piece of code which you
 +
  # want to run when an error has occured
 +
end
 +
</syntaxhighlight>}}
 +
 
 +
Also don't forget to place some comments in your code so you (and others) can understand why code blocks are needed and what they are used for. You will not be able to remember why you wrote most code blocks, but you will be able to see the logic when each reason is given. Hopefully your expanded code works as expected. If you can't find out why it doesn't run then compare it to [http://techbase.kde.org/Development/Tutorials/Plasma/Ruby/SimplePasteAppletCompleted this] finished and commented applet code.
 +
 
 +
== Learning all about Ruby ==
 +
 
 +
Now that you know how to set up a basic plasmoid in Ruby and learned how to research features seen in other plasmoids and expand your own plasmoid, it is time to learn all about Ruby itself.
 +
 
 +
For this you can use other tutorials which teach you nothing but Ruby. These will explain why you have been doing things the way they are described above. They will have example applications using text input, and it is your task to make such examples into plasmoids with line_edit widgets and buttons which reset, advance or do other stuff with your sample code. Only when you can rewrite your code yourself will you have become a programmer. My favorite Ruby tutorial is: [http://pine.fm/LearnToProgram/ Learn To Program].
 +
 
 +
You could also try looking at some [http://websvn.kde.org/trunk/KDE/kdeexamples/plasma/ruby/ Ruby Plasma examples]. These are written a bit different then the example described above, but they should still be useful.
  
 
If you have any questions about Plasma development there are several ways to ask for help. First of all there is the [https://mail.kde.org/mailman/listinfo/plasma-devel Plasma  mailinglist]. Secondly you can hop by on IRC, #plasma on irc.freenode.org. As a third option you could try asking you question on the [http://forum.kde.org/ KDE forums].
 
If you have any questions about Plasma development there are several ways to ask for help. First of all there is the [https://mail.kde.org/mailman/listinfo/plasma-devel Plasma  mailinglist]. Secondly you can hop by on IRC, #plasma on irc.freenode.org. As a third option you could try asking you question on the [http://forum.kde.org/ KDE forums].
  
 
Good luck, and don't forget to publish your Plasma applet on kde-look.org!
 
Good luck, and don't forget to publish your Plasma applet on kde-look.org!

Latest revision as of 21:54, 29 June 2011

Contents

[edit] Abstract

This tutorial will explain how to make simple KDE Plasma applet using Ruby. The applet will be a simple version of the paste applet. It will allow the user to put a bit of text on the clipboard.

[edit] Getting started

Before you get started you need to make sure to have the following installed on your computer.

  • KDE 4.2 or later
  • Ruby 1.8
  • KDE Ruby bindings and Plasma scriptengine

These packages can usually be installed through your distributions package manager.

[edit] Package layout

Plasma applets written in Ruby can be distributed as a plasmoid package. A minimal Ruby plasmoid package has the following structure:

  • contents/
    • code/
      • main.rb
  • metadata.desktop

The Ruby code for the plasmoid should be put in a file called main.rb in the contents/code folder of your package. The metadata.desktop file holds metadata about your plasmoid. This includes your name, name of your applet and a description. The metadata.desktop file is in the common .desktop file format, which looks a lot like an old INI file.

A minimal metadata.desktop file looks like this:

[Desktop Entry]
Name=Simple Ruby applet
Comment=This is a simple applet written in Ruby
Icon=chronometer
Type=Service
ServiceTypes=Plasma/Applet
 
X-Plasma-API=ruby-script
X-Plasma-MainScript=code/main.rb
 
X-KDE-PluginInfo-Author=Me
X-KDE-PluginInfo-Email=me@example.com
X-KDE-PluginInfo-Name=ruby-test
X-KDE-PluginInfo-Version=0.1
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

[edit] Code

Let's first start with the most basic Ruby applet and work from there. Every Plasma applet you're going to make in Ruby has to have a class which inherits the PlasmaScripting::Applet class. You can think of this as your main class for your applet. It will always have at least two methods, initialize and init. While these two seem very similar, there is an important difference. The initialize method is Ruby's default constructor. It will be called by the Ruby interpreter when an object of your class gets initialized (a.k.a. constructed). The init method gets called by Plasma. Plasma calls this method after the applet has been loaded. You can therefore assume that everything is set up when init is called, while with initialize, you only know your applet class is ready.

Start your code file with requiring 'plasma_applet' and opening a module. A minimal Ruby Plasma applet looks like this:

require 'plasma_applet'
 
module RubyTest
  class Main < PlasmaScripting::Applet
    def initialize parent
      super parent
    end
 
    def init
      set_minimum_size 150, 150
    end
  end
end

The module name must match the name you specify in metadata.desktop on the X-KDE-PluginInfo-Name line. The name ruby-test translates to a module name of RubyTest.

The only line in the init method now is set_minimum_size. This, as the name suggests, sets the minimum size for the applet.

To run your applet, you have two options. You can install it first, and then run it. Or, if you're running KDE 4.3 or later, just run it.

[edit] Installing your appliet

This is where plasmapkg comes in. It's a small tool which installs and upgrades Plasma packages. To put your code in a package, create a package structure as described in the above section. Outside the package folder run plasmapkg -i <package folder name>, plasmapkg will now install your applet.

mkdir ruby-test-applet
cd ruby-test-applet
# Copy or create metadata.desktop
mkdir contents
cd contents
mkdir code
cd code
# Copy or create main.rb
cd ../../..
plasmapkg -i ruby-test-applet

plasmapkg can install and upgrade Plasma packages. Since you've now installed your applet, you need to upgrade it after making changes. This isn't much different then installing, just use the -u commandline switch instead of -i.

[edit] Running your applet

You can run your applet using a tool called plasmoidviewer.

[edit] KDE 4.2

In KDE 4.2 plasmoidviewer takes the name of an installed applet as a parameter. The name of your applet is specified with the X-KDE-PluginInfo-Name line in your metadata.desktop file. You should be able to view your applet after installing it.

plasmoidviewer ruby-test

[edit] KDE 4.3

In KDE 4.3 plasmoidviewer still accepts the name of an installed applet as a parameter. But it can also run without a parameter. It will then try to run a plasmoid from the current directory. In order for this to work, the current directory should have the metadata.desktop file, the contents folder and the name of the directory should exactly match the name of the applet as specified in metadata.desktop.

plasmoidviewer

[edit] A label on an applet

When you have a very basic applet running, you can go two ways. You can put QWidgets on your applet, or draw the applet yourself by implementing the paintInterface method. I like to use standard widgets most of the time, so we're going to place some QWidgets on the plasma applet.

Plasma has a couple of themed widgets. A list can be found in the Plasma API. To place these widgets on your applet, you need a layout. The layout you'll be using most of the time will be the GraphicsLinearLayout, which basically puts your widgets in a horizontal or vertical line.

When putting a Plasma::Label on an applet in a GraphicsLinearLayout, you'll get the following code:

require 'plasma_applet'
 
module RubyTest
  class Main < PlasmaScripting::Applet
    def initialize parent
      super parent
    end
 
    def init
      set_minimum_size 150, 150
 
      label = Plasma::Label.new self
      label.text = 'This is a label on a plasmoid, hello Plasma!'
 
      layout = Qt::GraphicsLinearLayout.new self
      self.layout = layout
      layout.add_item label
    end
  end
end

In the init method we create a Plasma::Label and assign it a text. The first argument to the constructor of Plasma::Label (the new) is the parent of the label, in this case our applet. Next we create a GraphicsLinearLayout, assign it to the applet and put our label on it.

Ktip.png
 
Tip
In Ruby, instance variables always begin with an '@' character. All variables without an '@' are local variables. Variables with two @ signs are class (a.k.a. static) variables.


Ktip.png
 
Tip
The Ruby keyword self is a reference to the current instance of the class you're in. You can compare it with the this keyword in other languages like C++ and Java.


To view your applet, run plasmapkg -u <folder name> and plasmoidviewer <plasmoid name>.

plasmapkg -u ruby-test-applet
plasmoidviewer ruby-test

This will show you a nice and simple Hello World in Plasma.

[edit] A line edit and a button

Let's continue by adding a line edit and a button with some functionality.

To add a line edit widget we can use the Plasma::LineEdit class. This class is a basic KLineEdit (a text field with one line) themed for Plasma. To add it to our applet, we do the same as with the label. But since we want the line edit to be empty, we don't set a text.

Next is a push button. We can use the Plasma::PushButton class for that. Adding it is exactly the same as adding the label.

With a line edit and button in place, we should let the button do something when it's clicked. Qt, the library on which KDE is based, uses a mechanism called 'signals and slots'. You could compare it to action or event handlers in other languages or frameworks. Normally, one would connect a certain signal (event) to a certain slot (event handler method). Since we're using Ruby, we can't only do that, we can connect a signal to a code block. The syntax for this is easy:

button.connect(SIGNAL(:clicked)) do
  # do something
end

Now, when the button gets clicked, the code in the block gets executed.

Ktip.png
 
Tip
The Ruby language has the concept of code blocks. These are anonymous functions which you can supply to a method. A code block gets executed when the receiving method calls it.


We will do something simple when the button gets pressed. Qt makes it very easy to put some text on the clipboard, so let's do that. To put text on the clipboard we need Qt::Application.clipboard. This object has the very convenient method text= which puts text on the clipboard.

Putting it all together, we have to following code:

require 'plasma_applet'
 
module RubyTest
  class Main < PlasmaScripting::Applet
    def initialize parent
      super parent
    end
 
    def init
      set_minimum_size 150, 150
 
      layout = Qt::GraphicsLinearLayout.new Qt::Vertical, self
      self.layout = layout
 
      label = Plasma::Label.new self
      label.text = 'This plasmoid will copy the text you enter below to the clipboard.'
      layout.add_item label
 
      line_edit = Plasma::LineEdit.new self
      layout.add_item line_edit
 
      button = Plasma::PushButton.new self
      button.text = 'Copy to clipboard'
      layout.add_item button
 
      button.connect(SIGNAL(:clicked)) do
        Qt::Application.clipboard.text = line_edit.text
      end
    end
 
  end
end

[edit] Reading API reference documentation

Now that you have this simple but working Ruby Plasma applet, you can expand it. You can start by trying out some of the other Plasma widgets available. The official Plasma API is unfortunately written for C++. But with a little imagination and some logic you should be able to make use of it.

Still reading this tutorial? Let's take it step by step then.

Look through the Plasma API hierachy and find the LineEdit class. At the top of its own page is a listing of the available Signals. Duplicate the code for the button signal in your text editor:

button.connect(SIGNAL(:clicked)) do
  Qt::Application.clipboard.text = line_edit.text
end
 
button.connect(SIGNAL(:clicked)) do
  Qt::Application.clipboard.text = line_edit.text
end

And now reuse that code block to make your line edit variable also paste the typed content to the clipboard when the return key on the keyboard is being pressed. Save and run your code (in KDE 4.2 you must not forget to update manualy, in KDE 4.3 you can run 'Plasmoidviewer' when Konsole is pointing to the folder / directory of your Applet). My clipboard missed a few pastes but both the button and pressing return worked. Look a bit lower on the Class page for LineEdit: the C++ code to signal an action looks different then the Ruby signal you copied and the Ruby signal you composed yourself, but it does list in which KDE version the signal has become available.

Now you know how to let your Plasma Applet react to any signal and you know how to find all available signals in Plasma.

[edit] Enabling Public Member Functions

The second list at the top of the lineEdit class page of the API reference documentation names all the Public Member Functions. These are the extra features which we can use for the line_edit class. A nice looking feature is the clear button, which can appear when some text is typed and when clicked with the mouse pointer clears the text, so the user of your widget can type something different. The page mentions two functions related to the clear button for C++ programmers. In Ruby however the functions are cleanly united by the Ruby Qt bindings. So remember you must drop both is and set from the function to make it a Ruby method. The class page also says that this function uses only a true or false boolean parameter, indicated on the class page by the word "bool". To enable the clear button feature we must insert the parameter true with following code:

line_edit.clear_button_shown = true

Notice that the Ruby Qt bindings allows us to use underscores which increases the readability of all methods for non-native English speakers. So "setClearButtonShown (bool show)" becomes either "clear_button_shown = true" or clear_button_shown = false". Also remember that when scrolling down the class page it states that this feature only works in Plasma version 4.3 or later. This means that on earlier versions your plasmoid application will suddenly not run at all and give an error. For optional features not available in earlier versions of Plasma we should always tell the applet not to run the code when it gives an error. So now we will place the line inside a rescue operation which does nothing but skip the code when it gives an error:

begin
  line_edit.clear_button_shown = true
rescue
end
Ktip.png
 
Tip
Ruby exception handling allows you to do something else when a block of code gives an error or just skip the code block completely. It works like this:
begin
  # the piece of code which may error 
  # when the program is used
rescue
  # the optional piece of code which you 
  # want to run when an error has occured
end


Also don't forget to place some comments in your code so you (and others) can understand why code blocks are needed and what they are used for. You will not be able to remember why you wrote most code blocks, but you will be able to see the logic when each reason is given. Hopefully your expanded code works as expected. If you can't find out why it doesn't run then compare it to this finished and commented applet code.

[edit] Learning all about Ruby

Now that you know how to set up a basic plasmoid in Ruby and learned how to research features seen in other plasmoids and expand your own plasmoid, it is time to learn all about Ruby itself.

For this you can use other tutorials which teach you nothing but Ruby. These will explain why you have been doing things the way they are described above. They will have example applications using text input, and it is your task to make such examples into plasmoids with line_edit widgets and buttons which reset, advance or do other stuff with your sample code. Only when you can rewrite your code yourself will you have become a programmer. My favorite Ruby tutorial is: Learn To Program.

You could also try looking at some Ruby Plasma examples. These are written a bit different then the example described above, but they should still be useful.

If you have any questions about Plasma development there are several ways to ask for help. First of all there is the Plasma mailinglist. Secondly you can hop by on IRC, #plasma on irc.freenode.org. As a third option you could try asking you question on the KDE forums.

Good luck, and don't forget to publish your Plasma applet on kde-look.org!


This page was last modified on 29 June 2011, at 21:54. This page has been accessed 8,815 times. Content is available under Creative Commons License SA 3.0 as well as the GNU Free Documentation License 1.2.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V.Legal