Plasmoid
from http://www.ibm.com/developerworks/cn/linux/l-kde-plasmoids/index.html?ca=drs-cn-0720
KDE 4 plasmoid 简介
KDE 4 的桌面 shell Plasma 使用简单的 Plasma applet(plasmoid)改善桌面体验 developerWorks
级别: 中级
Martyn Honeyford, 高级 Java 开发人员
2009 年 7 月 20 日
KDE 4 包括许多振奋人心的新技术,其中包括 Plasma,该特性构成了 KDE 4 的桌面 shell。下面让我们看看如何编写简单 的 Plasma applet(称为 plasmoid)以显著改善桌面体验,以及如何将一个 plasmoid 变成一个简单的内存监控器。
KDE,即 K Desktop Environment(K 桌面环境),是一个基于桌面环境的免费软件项目,它针对 UNIX® 等系统。它为日常操作提供基本的桌面函数和应用程序,并为开发人员提供工具和文档,帮助他们为系统编写独立应用程序。KDE 软件基于 Qt 工具箱。第四代 KDE 的核心是一个重新设计的桌面环境和面板(统称为 Plasma),它将 Kicker、KDesktop 和 SuperKaramba 的功能整合到一种技术中。
KDE 4 带来了新希望
K 桌面环境(KDE)的第四个主要版本于 2008 年 1 月发布,并且得到了各种的评价。这个版本有以下主要变化:
- KDE 3 的大部分基本代码完全重新编写。
- 创建了大量的新技术。
- 大部分基本代码以某种方式重构。
尽管初始的 4.0 版本显示出极大的潜力,但修改范围意味着这个版本不会与 KDE 3 具有相同的功能。因此,很多用户报告说该版本在某些领域不稳定,一些用户不愿意升级到这个版本。4.1 版本解决了这些问题的大部分,但仍然缺少一些特性。
但是,随着 2009 年 1 月 KDE 4.2 版本的发布,这些问题中的大多数都得到了解决,许多用户决定使用 4.2 版本作为他们的主要桌面环境。
由于如此多的用户已经开始使用这个版本,现在是深入了解这些新功能和新技术的好时机。
KDE 4.2 使桌面焕发生机
本文主要关注一种最激动人心的新技术:Plasma 和 Plasma applet(它们通常称为 plasmoid)。
Plasma 后面的理念很简单:您拥有一个或多个 Plasma 容器,这些容器是一些可显示的元素,能够包含一些单独的项目,比如 widgets/plasmoids 和/或其他 Plasma 容器。
这个理念听起来并不是特别具有突破性,除非您意识到这个事实:在 KDE 4 之下,整个桌面 shell(向用户显示的主桌面)实际上就是一个 Plasma 容器,并且所有常用控件(比如任务栏、任务清单、时钟、任务, 任务切换器、K 菜单、快速启动图标等)都是通过 Plasma applet(比如时钟)或 Plasma 容器(比如任务栏)实现的。
这一点非常令人振奋。它为 KDE 4 用户提供许多的自定义机会,允许开发人员和/或个人用户更改桌面体验的几乎每个方面,在需要的地方完全更改其行为。例如,如果您想要一个比默认应用程序启动器功能更强大的应用程序启动器,您可以使用一个诸如 Lancelot(正在开发过程中)这样的启动器。如果空间有限,自己编写一个在轻量级的 DE(比如 XFCE)中常见的应用程序启动器(在轻量级的 DE 中右键单击将显示一个简单的弹出菜单),删除常规启动器以提供更多的屏幕空间。
这个简单的理念允许 KDE 4 转变成自适应桌面,因为发行版和用户能够使 KDE 适应不同的配置。例如,高配置的机器能够受益于复杂的大型 applet 和所有附件,而低配置的机器则可以依靠所需组件的简单/轻量级版本并删除 不需要的组件。 这样,您不再需要替换 KDE 4 以支持一个更专业的、轻量级的 DE。
尽管这些 Plasma applet 可能有些复杂,它们原本是您希望总是处于打开状态的工具风格的小型应用程序,而不是完整的应用程序。它们通常嵌入到桌面和/或任务栏中,典型的例子有系统监控器、即时消息器、社交网络工具等。
另一个公共的设计功能是它们占用较小的屏幕空间。您不希望看到许多 plasmoid 总是在桌面上打开而没有重叠。它们不在窗口管理器中显示为独立的窗口,因此您不能在它们之间快速移动或将其最小化。
除了提供基本的 Plasma 容器技术,KDE 开发人员已经着手编写强大的 Plasma applet,并尽量使其简便灵活。这些 applet 包括以下功能:
- 对所有 GUI 元素的可缩放矢量图形(Scalar Vector Graphics,SVG)的一流支持。 这样,所有的应用程序/applet 的分辨率将独立于平滑缩放。在 30 英寸高分辨率监控器和 8 英寸上网本屏幕上,同一个应用程序的外观和行为将表现正常 — 而无需开发人员进行其他处理。
- 对主题的出色支持。我们积极支持开发人员引用所有资源(如图标和背景等)。引用时要使用相对路径,这样 KDE 能够根据当前选择的主题在运行时定位这些资源。这将允许所有 KDE 4 应用程序在不同的主题之间利用统一的外观,这同样不需要开发人员进行额外处理。
- 多语言支持。KDE 4 plasmoid(比如常用 KDE 应用程序)能够使用几种不同的编程语言编写。本文关注 C++,但其他语言(比如 Ruby、Python 和 Javascript)正在开发过程中。
- 组件重用。KDE 很好地支持组件重用各组件相互提供的服务。
现在您对 Plasma 的背景有了一些了解,让我实际编写一个简单的 plasmoid 并添加到我们的 KDE 4.2 桌面中。
KDevelop 4 IDE
这些指令假定您正在运行一个 KDE 4.2 桌面。这些指令的一部分或全部可能可以应用于 KDE 4.1,但我没有验证这一点。
首先,您需要安装所有的 KDE 开发库、标题等。
我使用的是 Kubuntu 8.10 (Intrepid Ibex)的 Stable 版本,该版本默认提供 KDE 4.1,所以我必须启用 PPA 库以获取 KDE 4.2 和标题。 (参见 http://www.kubuntu.org/news/kde-4.2 以了解详细信息)。(Kubuntu 9.04 不需要这个步骤,但安装 g++ 和 kdesdk 等一定需要该步骤)。注意,Canonical 当前不支持这个版本的 KDE,所以最好使用开发环境而不是您的主机。
添加 PPA 库之后,我安装了 kdesdk、g++、cmake 和一些 kde-dev 包。操作如下:
清单 1. 构建 KDE 开发环境
sudo apt-get update sudo apt-get install kdesdk install cmake sudo apt-get install g++ sudo apt-get install libphonon-dev libplasma-dev
上述操作在我的机器上安装了我需要的组件。如果您使用的是另一个发行版,您需要决定如何安装这些包。
KDevelop 4 拥有一个不错的模板,用于自动生成一个基本的 plasmoid。遗憾的是,在编写时,KDevelop 4 仍旧处于 beta 版阶段,没有二进制版本可用于 Intrepid。因此,为了执行以下操作,您需要跟随这些比较直观的 指令,使用源代码构建它。
什么情况不应该使用 KDevelop 如果您不想使用 KDevelop,我向您推荐这篇优秀的 KDE 基础技术文章 Getting Started,它解释了一些基础理论。如果您跟随其中的步骤,您创建的项目将与我们使用 KDevelop 创建的项目非常相似。这样,您可以跳到这个部分 修改示例。
运行 KDevelop 之后(如图 1 所示),打开 Project,选择 New From Template。对话框出现后,扩展 C++,然后 KDE 展开并选择 Plasma Applet Template。下一步填充 Application name(我建议使用 dwPlasmoid)。然后单击 Next 和 Finish。
图 1. 创建项目 创建项目对话框
最终对话框要求您选择一个 Installation Prefix 目录(我推荐使用 $HOME/plasmoids)和一个构建类型(选择 Release 或 Debug)。
这将创建一个项目。花一些时间查看文档编写得很好的 .cpp 和 .h 文件。另外,前面提到过的基础技术文档 进一步解释了这些代码正在进行的操作。
现在您已创建一个项目,准备好构建它了。要构建项目,打开 Project 并选择 build(或者按下 F8 键)。该命令第一次将调用 configure,下次执行时,它将直接构建。
假设构建成功执行,从 Project 菜单选择 Install。这个命令将安装文件复制到此前选择的目录中。如果操作没有出现问题,您就准备好进行测试了。
在运行新的 plasmoid 之前,您需要告知 KDE 它的存在。首先,您需要使 KDE 注意到这个 plasmoid 的安装目录($HOME/plasmoids)。为此,需要打开控制台以便设置 KDEDIRS 环境变量,然后运行 kbuildsyscocoa4 命令。打开一个终端并输入清单 2 中的命令行:
清单 2. 使 KDE 注意到 plasmoid 的位置
export KDEDIRS=$KDEDIRS:$HOME/plasmoids kbuildsyscocoa4
现在 KDE 知道了 plasmoid 的位置,您可以尝试运行它。plasmoidviewer 是一个方便的工具,可以用于进行测试。要获取这个工具,输入 plasmoidviewer dwplasmoid。您将会看到示例 plasmoid 显示在一个窗口中(如图 2 所示)。
图 2. 基础的 plasmoid 基础 plasmoid 的屏幕截图
由于这是一个 plasmoid,您也可以将它嵌入到桌面中。但是,如果您试图现在添加这个 plasmoid(使用桌面上的 Add widgets 菜单,您将在 plasmoid 的清单中看到 dwPlasmoid,但是如果您试图添加它,它将不会有效!尽管您在运行 kbuildsyscocoa4 时正确设置了 KDEDIRS,但是在这个 Plasma 桌面启动时,它没有在环境中正确设置,所以它不能找到需要的所有文件。
要修复这个问题,可以退出当前运行的 Plasma 实例并从命令行重新启动它(使用此前使用的那个命令行以便 KDEDIRS 仍旧正确设置,也可以在运行以下命令前重新设置它)。注意,这将优雅地退出 Plasma 并重新启动它,因此确保您的操作不会被这种退出中断(例如,在其他 plasmoid 中保存任何未保存的工作)。使用清单 3 中的命令退出当前 Plasma 实例。
清单 3. 退出当前 Plasma 实例
kquitapp plasma && kstart plasma
现在可以将这个 plasmoid 添加到桌面了,它将在桌面上一直显示它的简单的图标和消息。您甚至可以添加它们中的三个并利用其内置的缩放和旋转功能(如图 3 所示):
图 3. 桌面中嵌入的多个 plasmoid 实例 桌面中嵌入的多个 plasmoid 实例的屏幕截图
上述方法的另一种替代方法是将安装目录设置为 /usr(假设这个目录是 KDE 在统上的安装目录)。这将导致安装步骤失败,除非您作为一个超级用户运行 KDevelop(或者您作为超级用户手动安装,方法是切换到构建目录 $HOME/projects/dwPlasmoid/build,然后运行sudo make install)。
注意:如果您希望在桌面上保留这些 plasmoid 并希望它们在重启后继续工作而不必再次停止和启动 Plasma,您需要告知 KDE 4 在启动时查看您的 plasmoid 目录。实现这个目的的一种方法是在您的 kde4rc 文件(/etc/kde4rc)中添加一行(如清单 4 所示)。
清单 4. 告知 KDE 在启动时查看 plasmoid 目录
[Directories] prefixes=/home/martynh/plasmoids
修改示例
好了,现在我们拥有了一个简单的 plasmoid,让我们用它完成一些更有趣的任务,而不是只显示静态文本。让我们将这个 plasmoid 转变为一个简单的内存监控器。
首先,通过删除图标和背景试图从这个窗口删除一些杂乱的东西。在构建器(dwPlasmoid::dwPlasmoid)中,您将注释掉设置背景的代码(如清单 5 所示):
清单 5. 注释掉设置背景的代码
// setBackgroundHints(DefaultBackground); // m_svg.setImagePath("widgets/background");
下一步,在绘图界面方法(dwPlasmoid::paintInterface)中,注释掉添加图标的部分(如清单 6 所示):
清单 6. 注释掉添加图标的代码
// p->ldrawPixmap(7, 0, m_icon.pixmap((int)contentsRect.width(), (int)contentsRect.width()-14)); // p->save();
如果您像以前一样重新构建并重新运行,您将看到这个窗口只是一个带有 Hello Plasmoid 文本的黑色窗口(如图 4 所示):
图 4. 背景和图标删除后的 Plasmoid 背景和图标删除后的 Plasmoid 的屏幕截图
接下来,使用一些更有用的文本替代窗口中的文本:一些关于内存使用情况的实时信息。
如果您熟悉 Linux®,您也许知道 /proc 目录下有一些提供运行系统的实时信息的特殊文件。我们感兴趣的文件是 /proc/meminfo。可以通过输入以下命令 cat /proc/meminfo 检查这个文件的内容。这个命令显示关于系统内存当前状态的大量信息。
让我们修改已经构建的程序,使其定期读取这个文件并在这个 plasmoid 中显示信息。首先读取文件并提取信息。幸运的是,Qt 工具箱使这个过程相对轻松。
您将要创建一种新方法并在这个类中添加一些新的成员变量。在这个头文件中,将该方法添加为一个 slot(如清单 7 所示,您将很快明白这样做的原因):
清单 7. 将方法添加为 slot
public slots: void updateMemoryCount();
下面,添加一些新的私有变量(如清单 8 所示):
清单 8. 添加一些新的私有变量
private: Plasma::Svg m_svg; KIcon m_icon; int m_totalMemory; int m_freeMemory; int m_swapMemory; int m_freeSwapMemory;
然后,将这个实现放到 cpp 文件中(如清单 9 所示):
清单 9. 将实现添加到 cpp 文件中
#include <QFile> ... void dwPlasmoid::updateMemoryCount() { // open the file QFile file("/proc/meminfo"); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { exit(-1); } QTextStream in(&file); QString line = in.readAll(); // remove any extraneous characters line = line.simplified(); // extract the information we are interested in using a regular expression QRegExp regex("MemTotal: (\\d+).*MemFree: (\\d+).*SwapTotal: (\\d+)" ".*SwapFree: (\\d+)"); regex.indexIn(line); m_totalMemory = (regex.cap(1).toInt()); m_freeMemory = (regex.cap(2).toInt()); m_swapMemory = (regex.cap(3).toInt()); m_freeSwapMemory = (regex.cap(4).toInt()); // force a re-draw update(); }
这个方法打开文件,读取内容,然后用一个正则表达式提取我们感兴趣的值。
接下来,需要修改这个绘图方法(dwPlasmoid::paintInterface)来添加这个信息而不是现有消息(如清单 10 所示):
清单 10. 更改绘图方法
int percentageFreeMem = (m_freeMemory * 100) / m_totalMemory; int percentageFreeSwap = (m_freeSwapMemory * 100) / m_swapMemory; char message[256]; sprintf(message,"Total Memory: %d\nFree Memory: %d\nPercent free mem: %d\n" "Total Swap: %d\nFree Swap: %d\nPercent free swap: %d", m_totalMemory, m_freeMemory, percentageFreeMem, m_swapMemory, m_freeSwapMemory, percentageFreeSwap); p->setPen(Qt::white); p->drawText(contentsRect, Qt::AlignTop | Qt::AlignHCenter, message); p->restore();
最后,将一个对 updateMemoryCount 的调用放进构造器中,以便为这个内存数据 updateMemoryCount(); 读取初始值。
如果您编译并运行这个 plasmoid,您将看到它将显示运行时准确的内存的使用情况(如图 5 所示):
图 5. 静态内存监控器 静态内存监控器的屏幕截图
这是一种改进,但一个系统内存的静态显示并不总是那么有趣。这个难题的最后一步是如何使这个 plasmoid 在其生命周期中定期更新以提供当前读数。实现这一点很简单,因为您曾将这个更新方法声明为一个 slot。您只需将以下语句添加到这个 init 方法(如清单 11 所示):
清单 11. 使这个 plasmoid 定期升级
#include <QTimer> ... // kick off a refresh timer QTimer* m_timer = new QTimer(this); connect(m_timer, SIGNAL(timeout()), this, SLOT(updateMemoryCount())); m_timer->start(1000);
这段代码将启动一个定时器,该定时器每秒发射一次并调用 updateMemoryCount slot。
如果您编译并运行它,您将看到它每秒自动更新。
图 6. 嵌入桌面的动态更新内存的 plasmoid 嵌入桌面的动态更新内存的 plasmoid 的屏幕截图
注意,这些值不一定同步。这些 plasmoid 在不同的时间添加,所以它们在不同的时间启动定时器。
回页首
结束语
如上所见,您可以在很短的时间内编写出一个相对复杂的内存监控器并将其嵌入到桌面中。
Plasmoid 技术允许编写强大的通用工具/监控器。同样重要的是,plasmoid 技术也很简单,允许根据自己的需求编写非常专业的工具,这些工具能够完美地集成到您的桌面环境中。
我希望这篇文章能够给您带来一些灵感,使您编写出有趣的 plasmoid。请通过下面的评论部分与我和其他读者分享您的经验和成果。
回页首
下载
描述 名字 大小 下载方法 本文的代码示例 code.zip 23KB HTTP 关于下载方法的信息
参考资料
学习
- KDE UserBase wiki for Plasma 是开始学习 Plasma 桌面界面的最好地方,它是 “KDE 支柱” 之一。在创建第一个 plasmoid 时,您还将发现一个优秀的、非常详细的 教程。
- 这个KDevelop-Project 最初设计用于为 KDE 构建一个容易使用的 IDE。
- Kubuntu 是基于 KDE 和获奖的 Ubuntu 的用户友好的免费操作系统。
- 从这个包含 “五部分” 的系列文章的第一部分 IBM 开放协作解决方案:概述(developerWorks,2008 年 10 月)开始学习如何规划和实现 OCCS —— IBM 针对 Linux 的最好的协作软件和相关服务。
- 查看 developerWork 上 许多关于 KDE 的文章。
- 在 developerWorks Linux 专区 寻找为 Linux 开发人员(包括 Linux 新手入门)准备的更多参考资料,查阅我们 最受欢迎的文章和教程。
- 在 developerWorks 上查阅所有 Linux 技巧 和 Linux 教程。
- 随时关注 developerWorks 技术活动和网络广播。
获得产品和技术
- 使用可直接从 developerWorks 下载的 IBM 试用软件 构建您的下一个 Linux 开发项目。
讨论
- 加入My developerWorks 社区;您可以通过个人档案和定制主页获得符合自己的兴趣的 developerWorks 文章,并与其他 developerWorks 用户进行交流。
关于作者
Martyn Honeyford 于 1996 年从诺丁汉大学毕业,获得计算机科学理学学士学位。毕业后,他在多家公司担任软件工程师。由于他的国际滑板滑雪生涯没有任何起色,而且他必须通过玩电子游戏来付账单,所以他的日常工作是伦敦一家在线衍生品贸易公司的高级 Java 开发人员。