Development/Tutorials/Plasma4/GettingStarted: Difference between revisions

From KDE TechBase
(the K_Export should be in the .cpp file, not in the header)
No edit summary
Line 5: Line 5:
series=Plasma Tutorial|
series=Plasma Tutorial|


name=Creating your first Plasmoid|
name=创建第一个Plasmoid|


pre=[http://mindview.net/Books/TICPP/ThinkingInCPP2e.html C++], [http://www.trolltech.com/products/qt/ Qt], [[Getting_Started/Build/KDE4|KDE4 development environment]]|
pre=[http://mindview.net/Books/TICPP/ThinkingInCPP2e.html C++], [http://www.trolltech.com/products/qt/ Qt], [[Getting_Started/Build/KDE4|KDE4开发环境]]|


next=|  
next=|  
Line 13: Line 13:
reading=[[Development/Tutorials/CMake|CMake]]
reading=[[Development/Tutorials/CMake|CMake]]
}}
}}
==Abstract==
This tutorial needs KDE 4.2 (trunk) to build.
We are going to create a simple plasmoid in this tutorial. To keep things simple, we will only create a static plasmoid which will contain the following items:


* An SVG Image
==概述==
* Icon
本教程是基于KDE 4.2 (主干)的。
* Some nice text
这里我们准备介绍如何创建一个简单的Plasmoid。简单起见,我们创建一个包含下列物品的Plasmoid:
 
* 一个SVG图像
* 图标
* 一些文字


[[image:creatingyourfirstplasmoid1.png|frame|center]]
[[image:creatingyourfirstplasmoid1.png|frame|center]]


== The Code ==
== 代码 ==
=== The .desktop file ===
=== .desktop文件 ===
Every Plasmoid needs a .desktop file to tell plasma how it should be started and what name it carries.  
每个Plasmoid都需要一个.desktop文件,这会告诉Plasma他该如何启动并叫什么名字。


'''plasma-applet-tutorial1.desktop'''
'''plasma-applet-tutorial1.desktop'''
Line 47: Line 48:
</code>
</code>


The most important bits are the '''X-KDE-Library''' and '''X-KDE-PluginInfo-Name''', they are the "glue" between your class and plasma, without it, nothing will start.  For '''X-KDE-PluginInfo-Category''', refer to the [[Projects/Plasma/PIG | PIG]].
最重要的字段就是 '''X-KDE-Library''''''X-KDE-PluginInfo-Name''', 它们是Plasma和你那些类之间的"胶水",没有他们,什么都启动不了。对'''X-KDE-PluginInfo-Category''', 详见[[Projects/Plasma/PIG | PIG]].


=== The header file ===
=== 头文件 ===
This is the example header file. Comments have been added in the code for clarity.
这里有一个头文件的例子。代码加上注释,应该比较清楚了。


'''plasma-tutorial1.h'''
'''plasma-tutorial1.h'''
<code cppqt>
<code cppqt>
// Here we avoid loading the header multiple times
//避免多次加载
#ifndef Tutorial1_HEADER
#ifndef Tutorial1_HEADER
#define Tutorial1_HEADER
#define Tutorial1_HEADER
// We need the Plasma Applet headers
//添加Plasma Applet头文件
#include <KIcon>
#include <KIcon>
   
   
Line 65: Line 66:
class QSizeF;
class QSizeF;
   
   
// Define our plasma Applet
//定义自己的Plasma Applet
class PlasmaTutorial1 : public Plasma::Applet
class PlasmaTutorial1 : public Plasma::Applet
{
{
     Q_OBJECT
     Q_OBJECT
     public:
     public:
         // Basic Create/Destroy
         // 构造函数/析构函数
         PlasmaTutorial1(QObject *parent, const QVariantList &args);
         PlasmaTutorial1(QObject *parent, const QVariantList &args);
         ~PlasmaTutorial1();
         ~PlasmaTutorial1();
   
   
         // The paintInterface procedure paints the applet to screen
         // paintInterface:画出屏幕
         void paintInterface(QPainter *painter,
         void paintInterface(QPainter *painter,
                 const QStyleOptionGraphicsItem *option,
                 const QStyleOptionGraphicsItem *option,
Line 89: Line 90:


==== QRectF boundingRect() ====
==== QRectF boundingRect() ====
The <tt>boundingRect()</tt> function tells plasma the actual size of the plasmoid. This is important because we need to know how much space is taken on the screen.
<tt>boundingRect()</tt> 函数告诉Plasma这Plasmoid的实际大小。我们要知道他在屏幕上有多大。
{{tip|
{{提醒|
If you have issues with your plasmoid leaving pixels behind when dragging, this is usually a result of an incorrect boundingRect()
如果在拖拽是,像素异常,那很有可能是boundingRect()出问题了。
}}
}}


==== void paintInterface(QRectF contentsRect) ====
==== void paintInterface(QRectF contentsRect) ====
This can be considered the main function since it paints the plasmoid on to the screen. Here, you define how you want your plasmoid to look.
这可以算是个主函数了,他把Plasmoid画在屏幕上。也是在这里,你把你想要的效果显出来。
You should only paint in the boundaries defined by contentsRect and avoid using geometry(). When a plasmoid does not have a standard background, e.g. when it's disabled with a setBackgroundHints() call or it's in the panel, geometry() and boundingRect() behave the same; however, when the standard background is enabled (the usual case), the appplet will have a margin where it should not be painted
画边界是,应该使用contentsRect规定的边界,同时避免使用geometry()。如果Plasmoid没有标准背景时,例如在setBackgroundHints()调用中被禁了或者是个面板,geometry()和boundingRect()有相同的行为。然而,当标准背景激活时(通常情况),那小程序会有些不该画出的边框。




=== The actual work file ===
=== 实际文件 ===
Here is the body of the function, again with a lot of comments in between.
函数体,有很多注释。


'''plasma-tutorial1.cpp'''
'''plasma-tutorial1.cpp'''
Line 112: Line 113:
#include <plasma/theme.h>
#include <plasma/theme.h>


// This is the command that links your applet to the .desktop file
// .desktop文件与你的小程序相连的命令行
K_EXPORT_PLASMA_APPLET(tutorial1, PlasmaTutorial1)
K_EXPORT_PLASMA_APPLET(tutorial1, PlasmaTutorial1)


Line 122: Line 123:
{
{
     m_svg.setImagePath("widgets/background");
     m_svg.setImagePath("widgets/background");
     // this will get us the standard applet background, for free!
     // 有缺省标准背景,免费
     setBackgroundHints(DefaultBackground);
     setBackgroundHints(DefaultBackground);
     resize(200, 200);
     resize(200, 200);
Line 131: Line 132:
{
{
     if (hasFailedToLaunch()) {
     if (hasFailedToLaunch()) {
         // Do some cleanup here
         // 清除工作
     } else {
     } else {
         // Save settings
         // 保存设置
     }
     }
}
}
Line 140: Line 141:
{
{
   
   
     // A small demonstration of the setFailedToLaunch function
     //演示setFailedToLaunch函数的用法
     if (m_icon.isNull()) {
     if (m_icon.isNull()) {
         setFailedToLaunch(true, "No world to say hello");
         setFailedToLaunch(true, "没地方说你好!");
     }
     }
}  
}  
Line 153: Line 154:
     p->setRenderHint(QPainter::Antialiasing);
     p->setRenderHint(QPainter::Antialiasing);
   
   
     // Now we draw the applet, starting with our svg
     //画出小程序,从SVG开始
     m_svg.resize((int)contentsRect.width(), (int)contentsRect.height());
     m_svg.resize((int)contentsRect.width(), (int)contentsRect.height());
     m_svg.paint(p, (int)contentsRect.left(), (int)contentsRect.top());
     m_svg.paint(p, (int)contentsRect.left(), (int)contentsRect.top());
   
   
     // We place the icon and text
     // 放置图表和文字
     p->drawPixmap(7, 0, m_icon.pixmap((int)contentsRect.width(),(int)contentsRect.width()-14));
     p->drawPixmap(7, 0, m_icon.pixmap((int)contentsRect.width(),(int)contentsRect.width()-14));
     p->save();
     p->save();
Line 163: Line 164:
     p->drawText(contentsRect,
     p->drawText(contentsRect,
                 Qt::AlignBottom | Qt::AlignHCenter,
                 Qt::AlignBottom | Qt::AlignHCenter,
                 "Hello Plasmoid!");
                 "Plasmoid,你好!");
     p->restore();
     p->restore();
}
}
Line 171: Line 172:


==== K_EXPORT_PLASMA_APPLET ( <name>, <class> ) ====
==== K_EXPORT_PLASMA_APPLET ( <name>, <class> ) ====
This is a small but very important part that links your classname to the applet name in the .desktop file. If your applet doesn't seem to get loaded, there may be a difference between this declaration and your .desktop file
这是个很小但是很重要的部分,它把你的小程序名字和路径跟.desktop文件中的连接起来。 如果你的小程序没有加载,那也许你的申明和.desktop文件有差异。


{{tip|
{{tip|
The K_EXPORT_PLASMA_APPLET adds "plasma_applet_", please pay attention to this when setting up your .desktop file to avoid a name difference
K_EXPORT_PLASMA_APPLET会加上"plasma_applet_", 在设置.desktop文件时要格外小心,不要有差错。
}}
}}


==== Plasma/Svg ====
==== Plasma/SVG ====
As you can see in the example code we are using the {{class|Plasma::Svg}} object, there are some important things to note here.
如你所见,代码中我们使用了{{class|Plasma::Svg}}对象,这里我们还有些要说的。


First we're using a relative path '''widgets/background''' which causes {{class|Plasma::Svg}} to use {{class|Plasma::Theme}} to locate the SVG data. While {{class|Plasma::Svg}} does support loading arbitrary files when passed an absolute path, use relative paths from the theme as often as possible as it makes Plasma skinable and the individual plasmoids look like a combined whole instead of a group of separate unrelated applications. You can see a list of available image components on the [[Projects/Plasma/Theme|Plasma Theme page]].
我们使相对路径 '''widgets/background''',这样就会{{class|Plasma::Svg}}运用{运行(KDE应用就知道新的桌面文件了)。
{class|Plasma::Theme|主题}}来定位SVG数据。在{{class|Plasma::SVG}}中,我们可以传入一个文件的绝对地址,随时使用主题中的相对路径,这让Plasma看上去像一系列的应用而非互不相关的东西了。可以在[[Projects/Plasma/Theme|Plasma主题页面]]找到系列可用图像组件。


In either mode, {{class|Plasma::Svg}} can be used to draw a subset of the SVG file by passing it an element id that appears in the SVG document. As a good example, if you open the clock.svg file that ships with the default theme, you will see that it has a background, 3 handles (hour, minute and seconds) and a foreground (the glass). Due to the ability to put all the elements in one file the SVG file shows a clock. This is much nicer for artists compared to editing 5 separate files that they have to imagine on top of each other, and much nicer for performance as only one SVG renderer and one file read from disk is necessary.
各种模式, {{class|Plasma::Svg}}可以只画出SVG文件中的一部分,根据SVG文件中的一个元素。举例来说,如果打开主题自带的clock.svg文件,里面有好些东西,3个指针(小时,分,秒) 和表面(玻璃框)。SVG文件可以把所有的内容都放在一个文件里,这远比用五个单独文件一个个叠加要好得多,而且渲染一个SVG文件的性能远比从系统中读取多个文件要好得多。


==== setBackgroundHints(DefaultBackground) ====
==== setBackgroundHints(DefaultBackground) ====
Since drawing a background is a common function there is fast and easier way of doing it. By adding <tt>setBackgroundHints(DefaultBackground)</tt> to the code, the default Plasma background gets drawn behind your plasmoid. This not only saves you time and code, but creates a more consistent presentation for the user.
画背景是个常用函数,有许多更快更好的办法可以做到。代码中加上<tt>setBackgroundHints(DefaultBackground)</tt>,可以给你的Plasmoid后面加上缺省Plasma背景。这不仅节省了时间和代码量,还给用户一个稳定的界面。


==== The init() method ====
==== init()方法 ====
In the constructor you only tell plasma about the background and configuration file if any. You also set the start size in the constructor. After that, plasma will take care of any resizing and you never have to worry about size. In the <tt>init()</tt> method you initialize everything that needs to be initialize such as reading config data for example.
构造函数中,我们只是给出Plasma的背景和配置文件。我们还可以设置初始大小。之后,Plasma会负责变形相关事宜,我们就不操心了。在<tt>init()</tt>函数中,我们把一切都初始化了,例如读取配置文件等等。


==== hasFailedToLaunch() ====
==== hasFailedToLaunch() ====
If for some reason, the applet fails to get up on its feet (the library couldn't be loaded, necessary hardware support wasn't found, etc..) this method returns true. Using this function gives your application a chance to cleanup before quiting.
如果因为某些原因,小程序没能正常启动 (类库每家在,硬件不支持等..),这个方法就会返回真。用这个方法可以在推出前清理现场。


==== setFailedToLaunch(bool, QString) ====
==== setFailedToLaunch(bool, QString) ====
When your application is unable to start, this function allows you to inform Plasma and give an optional reason why. Plasma will then draw a standardized error interface to inform the user of the situation and your applet will not be called upon to do any drawing on its own from that point forward. If your plasmoid becomes more complex and depends on multiple factors this is the nicest way to cleanup.
当程序不能启动时,,这个函数通知Plasma并可以给出一个原因(可选)。Plasma会给出一个标准错误界面,告诉用户当前情况:这个小程序不会再运行了。如果你的Plasmoid变得复杂起来并依赖与很多因素,这是个很好的退出机制。


==== dataUpdated ====
==== dataUpdated ====
If you would connect to any of plasma's data-engines you would have to implement a function called dataUpdated in your plasmoid. The latter is called if the data-engine sends you data, i.e. your plasmoid should recalculate its contents.
如果你想连接到数据引擎,你就要实现这个方法-dataUpdated。数据引擎给你发数据时,这个函数就会被调用,,例如,Plasma要重新计算内容了等。


==== Determine the applet size and geometry: geometry() and contentsRect() ====
==== 确定小程序的大小和位置:geometry()和contentsRect() ====
If you need to know, in your applet code, what the applet size and geometry is, call contentsRect() and contentsRect().size(). Avoid calling geometry() and size() because they don't take into account the margin's size set by the applets default background.
如果在小程序里要知道当前的大小和位置,调用contentsRect()和contentsRect().size()。避免使用geometry()和size(),因为他们没有把背景边框计算在内。同样要避免使用小程序的绝对值,如避免用QPoint(0, 0)表示左上角,可以用contentsRect().topLeft()
Also avoid using absolute numbers to position items in the applet like QPoint(0, 0) to indicate the top-left point of your applet, instead use contentsRect().topLeft().


=== Building it all, the CMakeLists.txt ===
=== 全部联编,CMakeLists.txt文件 ===
Finally, to put everything together you need to build everything. To tell cmake what needs to go where there is the CMakeLists.txt file.  
最后,把所有的都汇总一起,准备联编。所有cmake要知道的内容都在CMakeLists.txt文件里了。


For more details on CMake please read [[Development/Tutorials/CMake]]
更多关于CMake请参见[[Development/Tutorials/CMake]]


<code bash>
<code bash>
# Project Needs a name ofcourse
#项目命名
project(plasma-tutorial1)
project(plasma-tutorial1)


# Find the required Libaries
#所需类库
find_package(KDE4 REQUIRED)
find_package(KDE4 REQUIRED)
include(KDE4Defaults)
include(KDE4Defaults)
Line 223: Line 224:
   )
   )


# We add our source code here
#我们的代码
set(tutorial1_SRCS plasma-tutorial1.cpp)
set(tutorial1_SRCS plasma-tutorial1.cpp)


# Now make sure all files get to the right place
# 确保所有文件都个就其位
kde4_add_plugin(plasma_applet_tutorial1 ${tutorial1_SRCS})
kde4_add_plugin(plasma_applet_tutorial1 ${tutorial1_SRCS})
target_link_libraries(plasma_applet_tutorial1  
target_link_libraries(plasma_applet_tutorial1  
Line 238: Line 239:
</code>
</code>


== Testing the Applet ==
== 测试小程序 ==
If your current Development Environment differs from the Test Installation, you have to run cmake with -DCMAKE_INSTALL_PREFIX=/usr/lib/kde4/ (replace with your $KDEDIR). Then run make. If succesfull the applet can be installed by running sudo make install
如果你的开发环境和你的测试环境不一致,,运行cmake时要加上 -DCMAKE_INSTALL_PREFIX=/usr/lib/kde4/ (或用你的$KDEDIR替换掉)。然后执行。成功的话,这个小程序就可以用"sudo make install"安装运行了,或
or
 
* cp ./lib/plasma_applet_tutorial1.so $KDEDIR/lib  
* cp ./lib/plasma_applet_tutorial1.so $KDEDIR/lib  
* cp ./plasma-applet-tutorial1.desktop $KDEDIR/share/kde4/services/
* cp ./plaand run kbuildsycoca4 a-applet-tutorial1.desktop $KDEDIR/share/kde4/services/


and run kbuildsycoca4 (so that KDE apps will know about the new desktop files).
可以在'''plasmoidviewer'''测试你的小程序:
In order to test your Applet you can use the '''plasmoidviewer''' program:
<code bash>
<code bash>
plasmoidviewer applet_name
plasmoidviewer applet_name
</code>
</code>
You can even view your Applet in a small desktop using plasmoidviewer:
可以用plasmoidviewer看看小程序的效果:
<code bash>
<code bash>
plasmoidviewer -c desktop applet_name
plasmoidviewer -c desktop applet_name
</code>
</code>


Where '''applet_name''' is the value specified into .desktop for the '''X-KDE-PluginInfo-Name''' key.
这里'''applet_name'''就是在.desktop文件里'''X-KDE-PluginInfo-Name'''的值。


Otherwise you can restart plasma, so the Applet will be displayed in the Applet Browser:
如果遇到问题,重启Plasma,小程序就会在Applet浏览器中显示了。
  kbuildsycoca4
  kbuildsycoca4
  kquitapp plasma # in trunk (KDE4.3): kquitapp plasma-desktop
  kquitapp plasma # in trunk (KDE4.3): kquitapp plasma-desktop
  plasma          # in trunk (KDE4.3): plasma-desktop
  plasma          # in trunk (KDE4.3): plasma-desktop


If that doesn't work you will have to restart your KDE session by logging out and back in. Or try to set export KDEDIRS=/usr/local:'kde4-config --prefix' and run kbuildsycoca4 again
如果还不行的话,重启KDE会话。或者设置"export KDEDIRS=/usr/local:'kde4-config --prefix'"再重新运行kbuildsycoca4。

Revision as of 07:10, 28 September 2009


Development/Tutorials/Plasma/GettingStarted


创建第一个Plasmoid
Tutorial Series   Plasma Tutorial
Previous   C++, Qt, KDE4开发环境
What's Next  
Further Reading   CMake

概述

本教程是基于KDE 4.2 (主干)的。 这里我们准备介绍如何创建一个简单的Plasmoid。简单起见,我们创建一个包含下列物品的Plasmoid:

  • 一个SVG图像
  • 图标
  • 一些文字

代码

.desktop文件

每个Plasmoid都需要一个.desktop文件,这会告诉Plasma他该如何启动并叫什么名字。

plasma-applet-tutorial1.desktop [Desktop Entry] Name=Tutorial 1 Comment=Plasma Tutorial 1 Type=Service ServiceTypes=Plasma/Applet

X-KDE-Library=plasma_applet_tutorial1 X-KDE-PluginInfo-Author=Bas Grolleman [email protected] X-KDE-PluginInfo-Name=plasma_applet_tutorial1 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

最重要的字段就是 X-KDE-LibraryX-KDE-PluginInfo-Name, 它们是Plasma和你那些类之间的"胶水",没有他们,什么都启动不了。对X-KDE-PluginInfo-Category, 详见 PIG.

头文件

这里有一个头文件的例子。代码加上注释,应该比较清楚了。

plasma-tutorial1.h //避免多次加载

  1. ifndef Tutorial1_HEADER
  2. define Tutorial1_HEADER

//添加Plasma Applet头文件

  1. include <KIcon>
  1. include <Plasma/Applet>
  2. include <Plasma/Svg>

class QSizeF;

//定义自己的Plasma Applet class PlasmaTutorial1 : public Plasma::Applet {

   Q_OBJECT
   public:
       // 构造函数/析构函数
       PlasmaTutorial1(QObject *parent, const QVariantList &args);
       ~PlasmaTutorial1();

       // paintInterface:画出屏幕
       void paintInterface(QPainter *painter,
               const QStyleOptionGraphicsItem *option,
               const QRect& contentsRect);

void init();

   private:
       Plasma::Svg m_svg;
       KIcon m_icon;

};

  1. endif

QRectF boundingRect()

boundingRect() 函数告诉Plasma这Plasmoid的实际大小。我们要知道他在屏幕上有多大。 Template:提醒

void paintInterface(QRectF contentsRect)

这可以算是个主函数了,他把Plasmoid画在屏幕上。也是在这里,你把你想要的效果显出来。 画边界是,应该使用contentsRect规定的边界,同时避免使用geometry()。如果Plasmoid没有标准背景时,例如在setBackgroundHints()调用中被禁了或者是个面板,geometry()和boundingRect()有相同的行为。然而,当标准背景激活时(通常情况),那小程序会有些不该画出的边框。


实际文件

函数体,有很多注释。

plasma-tutorial1.cpp

  1. include "plasma-tutorial1.h"
  2. include <QPainter>
  3. include <QFontMetrics>
  4. include <QSizeF>
  1. include <plasma/svg.h>
  2. include <plasma/theme.h>

// 把.desktop文件与你的小程序相连的命令行 K_EXPORT_PLASMA_APPLET(tutorial1, PlasmaTutorial1)


PlasmaTutorial1::PlasmaTutorial1(QObject *parent, const QVariantList &args)

   : Plasma::Applet(parent, args),
   m_svg(this),
   m_icon("document")

{

   m_svg.setImagePath("widgets/background");
   // 有缺省标准背景,免费
   setBackgroundHints(DefaultBackground);
   resize(200, 200);

}


PlasmaTutorial1::~PlasmaTutorial1() {

   if (hasFailedToLaunch()) {
       // 清除工作
   } else {
       // 保存设置
   }

}

void PlasmaTutorial1::init() {

   //演示setFailedToLaunch函数的用法
   if (m_icon.isNull()) {
       setFailedToLaunch(true, "没地方说你好!");
   }

}


void PlasmaTutorial1::paintInterface(QPainter *p,

       const QStyleOptionGraphicsItem *option, const QRect &contentsRect)

{

   p->setRenderHint(QPainter::SmoothPixmapTransform);
   p->setRenderHint(QPainter::Antialiasing);

   //画出小程序,从SVG开始
   m_svg.resize((int)contentsRect.width(), (int)contentsRect.height());
   m_svg.paint(p, (int)contentsRect.left(), (int)contentsRect.top());

   // 放置图表和文字
   p->drawPixmap(7, 0, m_icon.pixmap((int)contentsRect.width(),(int)contentsRect.width()-14));
   p->save();
   p->setPen(Qt::white);
   p->drawText(contentsRect,
               Qt::AlignBottom | Qt::AlignHCenter,
               "Plasmoid,你好!");
   p->restore();

}

  1. include "plasma-tutorial1.moc"

K_EXPORT_PLASMA_APPLET ( <name>, <class> )

这是个很小但是很重要的部分,它把你的小程序名字和路径跟.desktop文件中的连接起来。 如果你的小程序没有加载,那也许你的申明和.desktop文件有差异。

Tip
K_EXPORT_PLASMA_APPLET会加上"plasma_applet_", 在设置.desktop文件时要格外小心,不要有差错。


Plasma/SVG

如你所见,代码中我们使用了Plasma::Svg对象,这里我们还有些要说的。

我们使相对路径 widgets/background,这样就会Plasma::Svg运用{运行(KDE应用就知道新的桌面文件了)。 {class|Plasma::Theme|主题}}来定位SVG数据。在Plasma::SVG中,我们可以传入一个文件的绝对地址,随时使用主题中的相对路径,这让Plasma看上去像一系列的应用而非互不相关的东西了。可以在Plasma主题页面找到系列可用图像组件。

各种模式, Plasma::Svg可以只画出SVG文件中的一部分,根据SVG文件中的一个元素。举例来说,如果打开主题自带的clock.svg文件,里面有好些东西,3个指针(小时,分,秒) 和表面(玻璃框)。SVG文件可以把所有的内容都放在一个文件里,这远比用五个单独文件一个个叠加要好得多,而且渲染一个SVG文件的性能远比从系统中读取多个文件要好得多。

setBackgroundHints(DefaultBackground)

画背景是个常用函数,有许多更快更好的办法可以做到。代码中加上setBackgroundHints(DefaultBackground),可以给你的Plasmoid后面加上缺省Plasma背景。这不仅节省了时间和代码量,还给用户一个稳定的界面。

init()方法

构造函数中,我们只是给出Plasma的背景和配置文件。我们还可以设置初始大小。之后,Plasma会负责变形相关事宜,我们就不操心了。在init()函数中,我们把一切都初始化了,例如读取配置文件等等。

hasFailedToLaunch()

如果因为某些原因,小程序没能正常启动 (类库每家在,硬件不支持等..),这个方法就会返回真。用这个方法可以在推出前清理现场。

setFailedToLaunch(bool, QString)

当程序不能启动时,,这个函数通知Plasma并可以给出一个原因(可选)。Plasma会给出一个标准错误界面,告诉用户当前情况:这个小程序不会再运行了。如果你的Plasmoid变得复杂起来并依赖与很多因素,这是个很好的退出机制。

dataUpdated

如果你想连接到数据引擎,你就要实现这个方法-dataUpdated。数据引擎给你发数据时,这个函数就会被调用,,例如,Plasma要重新计算内容了等。

确定小程序的大小和位置:geometry()和contentsRect()

如果在小程序里要知道当前的大小和位置,调用contentsRect()和contentsRect().size()。避免使用geometry()和size(),因为他们没有把背景边框计算在内。同样要避免使用小程序的绝对值,如避免用QPoint(0, 0)表示左上角,可以用contentsRect().topLeft()。

全部联编,CMakeLists.txt文件

最后,把所有的都汇总一起,准备联编。所有cmake要知道的内容都在CMakeLists.txt文件里了。

更多关于CMake请参见Development/Tutorials/CMake

  1. 项目命名

project(plasma-tutorial1)

  1. 所需类库

find_package(KDE4 REQUIRED) include(KDE4Defaults)

add_definitions (${QT_DEFINITIONS} ${KDE4_DEFINITIONS}) include_directories(

  ${CMAKE_SOURCE_DIR}
  ${CMAKE_BINARY_DIR}
  ${KDE4_INCLUDES}
  )
  1. 我们的代码

set(tutorial1_SRCS plasma-tutorial1.cpp)

  1. 确保所有文件都个就其位

kde4_add_plugin(plasma_applet_tutorial1 ${tutorial1_SRCS}) target_link_libraries(plasma_applet_tutorial1

                     ${KDE4_PLASMA_LIBS} ${KDE4_KDEUI_LIBS})

install(TARGETS plasma_applet_tutorial1

       DESTINATION ${PLUGIN_INSTALL_DIR})

install(FILES plasma-applet-tutorial1.desktop

       DESTINATION ${SERVICES_INSTALL_DIR})

测试小程序

如果你的开发环境和你的测试环境不一致,,运行cmake时要加上 -DCMAKE_INSTALL_PREFIX=/usr/lib/kde4/ (或用你的$KDEDIR替换掉)。然后执行。成功的话,这个小程序就可以用"sudo make install"安装运行了,或

  • cp ./lib/plasma_applet_tutorial1.so $KDEDIR/lib
  • cp ./plaand run kbuildsycoca4 a-applet-tutorial1.desktop $KDEDIR/share/kde4/services/

可以在plasmoidviewer测试你的小程序: plasmoidviewer applet_name 可以用plasmoidviewer看看小程序的效果: plasmoidviewer -c desktop applet_name

这里applet_name就是在.desktop文件里X-KDE-PluginInfo-Name的值。

如果遇到问题,重启Plasma,小程序就会在Applet浏览器中显示了。

kbuildsycoca4
kquitapp plasma # in trunk (KDE4.3): kquitapp plasma-desktop
plasma          # in trunk (KDE4.3): plasma-desktop

如果还不行的话,重启KDE会话。或者设置"export KDEDIRS=/usr/local:'kde4-config --prefix'"再重新运行kbuildsycoca4。