现在可以将这个 plasmoid 添加到桌面了,它将在桌面上一直显示它的简单的图标和消息。您甚至可以添加它们中的三个并利用其内置的缩放和旋转功能(如图 3 所示):
图 3. 桌面中嵌入的多个 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
接下来,使用一些更有用的文本替代窗口中的文本:一些关于内存使用情况的实时信息。
如果您熟悉 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。请通过下面的评论部分与我和其他读者分享您的经验和成果。(责任编辑:A6)