Development/Tutorials/Plasma4/Ruby/SimplePasteApplet: Difference between revisions

    From KDE TechBase
    (I've wriiten a tutorial for Plasma and Ruby. It's still needs some work, but this is enough to get the idea.)
     
    (Minor changes to the text, put explanation of ruby and return statements in a note box.)
    Line 52: Line 52:
    == Code ==
    == 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 use a class which inherits the <tt>PlasmaScripting::Applet</tt> class. You can think of this as your main class for your applet. The class will always have at least two methods, <tt>initialize</tt> and <tt>init</tt>. While these two are very similar, there is an important distinction. The <tt>initialize</tt> method is Ruby's default constructor. It will be called by the Ruby interpreter when an object of your class gets initialized (hence the name). The <tt>init</tt> method on the other hand, gets called by Plasma. Plasma calls this method after the applet has been loaded. You can therefore assume that everything is set up when <tt>init</tt> is called, while with initialize, you only know your applet class is ready.
    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 <tt>PlasmaScripting::Applet</tt> class. You can think of this as your main class for your applet. It will always have at least two methods, <tt>initialize</tt> and <tt>init</tt>. While these two seem very similar, there is an important difference. The <tt>initialize</tt> 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 <tt>init</tt> 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 <tt>init</tt> is called, while with initialize, you only know your applet class is ready.


    Before you can open your main class, <tt>require plasma_applet</tt> and open 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>
    <code ruby>
    Line 72: Line 72:
    </code>
    </code>


    The module name must match the name you specify in metadata.desktop on the <tt>X-KDE-PluginInfo-Name</tt> line'. A name in <tt>metadata.desktop</tt> of <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>.


    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 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 new folder and put a <tt>metadata.desktop</tt> file in it (as shown above). Now put your code in a file called <tt>main.rb</tt> in <tt>contents/code</tt>. <tt>cd</tt> out of the folder and run <tt>plasmapkg -i <foldername></tt>. <tt>Plasmapkg</tt> will now install your 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.


    <code bash>
    <code bash>
    Line 91: Line 91:
    </code>
    </code>


    Now that your applet is installed, you can view it. For this there is 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 your <tt>metadata.desktop</tt> file. Launch <tt>plasmoidviewer</tt> and see your still empty Plasma applet running.
    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.


    <code bash>
    <code bash>
    Line 97: Line 97:
    </code>
    </code>


    As described earlier, <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>.
    <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>.


    == A label on an applet ==
    == A label on an applet ==


    Now that you have a very basic applet running, you can go two ways. You can put QWidgets on your applet, or draw your applet yourself by implementing <tt>paintInterface</tt>. I like to use standard widgets most of the time, so we're going to place some QWidgets on the plasma 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 <tt>paintInterface</tt> 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 [1]. To place these widgets on your applet, you need a 'layout'. The layout you'll be using most of the time will be the <tt>GraphicsLinearLayout</tt>, which basically puts your widgets in a horizontal or vertical line.
    Plasma has a couple of themed widgets. A list can be found in the Plasma API [1]. To place these widgets on your applet, you need a layout. The layout you'll be using most of the time will be the <tt>GraphicsLinearLayout</tt>, which basically puts your widgets in a horizontal or vertical line.


    Let's start by putting a Label on the applet and putting it in a <tt>GraphicsLinearLayout</tt>.
    When putting a <tt>Plasma::Label</tt> on an applet in a <tt>GraphicsLinearLayout</tt>, you'll get the following code:


    <code ruby>
    <code ruby>
    Line 131: Line 131:
    </code>
    </code>


    In order 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 [2]. 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.
    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 [2]. 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.


    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>.
    Line 154: Line 154:
    </code>
    </code>


    (Note that with Ruby, it's not required to specify the <tt>return</tt> keyword. This can be a bit confusing. It can also make a method very clear, I think this 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. )
    {{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 of 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.


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


    Now comes the interesting part, doing something with the button. 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[3].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[3]. The syntax for this is easy:


    <code ruby>
    <code ruby>
    Line 170: Line 170:
    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.


    In this tutorial we will do something simple when the button gets pressed. Qt makes it very easy to put some text on the clipboard, let's do that. To put text on the clipboard we need <tt>Qt::Application.clipboard</tt>. This object has the very convenient method <tt>text=</tt> which puts text on the clipboard.
    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 <tt>Qt::Application.clipboard</tt>. This object has the very convenient method <tt>text=</tt> which puts text on the clipboard.


    Putting it all together, we have to following code:
    Putting it all together, we have to following code:

    Revision as of 11:44, 18 January 2009

    Warning: This tutorial has not yet been completely tested and might contain incorrect information or examples.

    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.

    Getting started

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

    • KDE 4.2
    • Ruby 1.8
    • KDE 4.2 Ruby bindings

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

    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 [email protected] 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

    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 first need to install it. 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. Outsize the package folder run plasmapkg -i <package folder name>. Plasmapkg will now install your applet.

    mkdir ruby-test-applet cd ruby-test-applet

    1. Copy or create metadata.desktop

    mkdir contents cd contents mkdir code cd code

    1. Copy or create main.rb

    cd ../../.. plasmapkg -i ruby-test-applet

    Now that your applet is installed, you can view it. You can do this with a tool called plasmoidviewer. As argument it takes the name of your plasma applet specified with X-KDE-PluginInfo-Name in the metadata.desktop file. Launch plasmoidviewer and see your still empty Plasma applet running.

    plasmoidviewer ruby-test

    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.

    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 [1]. 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
         @parent = parent
       end
    
       def init
         set_minimum_size 150, 150
    
         label = Plasma::Label.new @parent.applet
         label.text = 'This is a label on a plasmoid, hello Plasma!'
    
         layout = Qt::GraphicsLinearLayout.new @parent.applet
         @parent.applet.layout = layout
         layout.add_item label
       end
     end
    

    end

    To place widgets on the applet, we need the applet's parent. This parent has a method called applet, which gives us a reference to the 'real' applet. To get to this applet, we save the parent in a instance variable [2]. In the init method we create a Plasma::Label and assign it a text. Next we create a GraphicsLinearLayout, assign it to the applet and put our label on it.

    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.

    A line edit and a button

    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 @parent.applet a lot. We can clean this up by defining a method called applet which returns @parent.applet.

    def applet

     @parent.applet
    

    end

    Note
    With Ruby, it's not required to write the return keyword. This can be a bit confusing for newcomers. But it can make a method very clear, I think the applet method is a good example of such a case. You are of course, free to put a return in front of the single line in the method.


    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[3]. 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.

    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
         @parent = parent
       end
    
       def applet
         @parent.applet
       end
    
       def init
         set_minimum_size 150, 150
    
         layout = Qt::GraphicsLinearLayout.new Qt::Vertical, applet
         applet.layout = layout
    
         label = Plasma::Label.new applet
         label.text = 'This plasmoid will copy the text you enter below to the clipboard.'
         layout.add_item label
    
         line_edit = Plasma::LineEdit.new applet
         layout.add_item line_edit
    
         button = Plasma::PushButton.new applet
         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

    Where to go from here

    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[1]. The official Plasma API is unfortunately written for C++ usage. 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.

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

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


    [1]: http://api.kde.org/4.x-api/kdelibs-apidocs/plasma/html/hierarchy.html

    [2]: 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.

    [3]: Explain blocks

    [4]: http://websvn.kde.org/trunk/KDE/kdebase/workspace/plasma/scriptengines/ruby/examples/applets/

    [5]: https://mail.kde.org/mailman/listinfo/plasma-devel

    [6]: http://forum.kde.org/