dde-dock/plugins/plugin-guide/plugins-developer-guide.md
石博文 184445992d add plugins develop guide
Change-Id: I448c791af97d6ce50a39dff542f843763883a3e1
2018-02-24 13:31:06 +08:00

5.5 KiB
Raw Blame History

从零构建 dde-dock 的插件

本教程将展示一个简单的 dde-dock 插件的开发过程,插件开发者可跟随此步骤为 dde-dock 创造出更多具有丰富功能的插件。

在本教程中,将创建一个可以实时显示用户家目录(~/)使用情况的小工具。

插件的工作原理

dde-dock 插件本质是一个按 Qt 插件标准所开发的共享库文件(so)。通过 dde-dock 预定的规范与提供的接口,共同完成 dde-dock 的功能扩展。

准备环境

插件的开发环境可以是任意的,只要是符合 Qt 插件规范及 dde-dock 插件规范的共享库文件,都可以被当作 dde-dock 插件载入。下面以 Qt + qmake 为例进行说明:

安装依赖

以 Deepin 15.5 环境为基础,至少先安装如下的包:

  • dde-dock-dev
  • qt5-qmake
  • qtbase5-dev-tools
  • libqt5core5a
  • libqt5widgets5
  • pkg-config

基本的项目结构

创建必需的项目目录与文件

插件名称叫做home_monitor,所以创建以下的目录结构:

home_monitor
├── home_monitor.json
├── homemonitorplugin.cpp
├── homemonitorplugin.h
└── home_monitor.pro

home_monitor.pro文件内容如下:

# 添加所需的 Qt 模块
QT              += widgets
# 指定生成目标为共享库
TEMPLATE         = lib
# 指定生成目标为 Qt 插件
CONFIG          += plugin c++11

# 指定生成目标的名称
TARGET          = $$qtLibraryTarget(home_monitor)
# 指定生成目标的目录
DESTDIR          = $$_PRO_FILE_PWD_
# 添加必要的文件到插件中
DISTFILES       += home_monitor.json

HEADERS += \
    homemonitorplugin.h

SOURCES += \
    homemonitorplugin.cpp

# 以下是安装相关的设定
isEmpty(PREFIX) {
    PREFIX = /usr
}

target.path = $${PREFIX}/lib/dde-dock/plugins/
INSTALLS += target

home_monitor.json文件指明了当前插件所使用的 dde-dock 的接口版本dde-dock 在加载此插件时会检测自己的接口版本是否与插件的接口版本一致当双方的接口版本不一致时dde-dock 为了安全将阻止加载对应的插件。

在 dde-dock 内建的插件代码中,可以找到当前具体的接口版本,目前只有 1.0 版本。

{
	"api": "1.0"
}

homemonitorplugin.h包含了类HomeMonitorPlugin,它继承自PluginItemInterface,这代表了它是一个实现了 dde-dock 接口的插件。

PluginItemInterface中包含众多的功能接口以丰富插件的功能,具体的接口功能与用法可以查看对应文件中的文档。大多数接口在没有特定需求的时候都是无需处理的,需要所有插件显式处理的接口只有pluginNameinititemWidget三个接口。

#ifndef HOMEMONITORPLUGIN_H
#define HOMEMONITORPLUGIN_H

#include <dde-dock/pluginsiteminterface.h>

#include <QObject>

class HomeMonitorPlugin : public QObject, PluginsItemInterface
{
    Q_OBJECT
    Q_INTERFACES(PluginsItemInterface)
    Q_PLUGIN_METADATA(IID "com.deepin.dock.PluginsItemInterface" FILE "home_monitor.json")

public:
    explicit HomeMonitorPlugin(QObject *parent = nullptr);

    // 返回插件的名称,必须是唯一值,不可以和其它插件冲突
    const QString pluginName() const override;
    // 插件初始化函数
    void init(PluginProxyInterface *proxyInter) override;

    // 返回插件的 widget
    QWidget *itemWidget(const QString &itemKey) override;
};

#endif // HOMEMONITORPLUGIN_H

homemonitorplugin.cpp中包含对应接口的实现

#include "homemonitorplugin.h"

HomeMonitorPlugin::HomeMonitorPlugin(QObject *parent)
    : QObject(parent)
{

}

const QString HomeMonitorPlugin::pluginName() const
{
    return QStringLiteral("home_monitor");
}

void HomeMonitorPlugin::init(PluginProxyInterface *proxyInter)
{
    m_proxyInter = proxyInter;
}

QWidget *HomeMonitorPlugin::itemWidget(const QString &itemKey)
{
    Q_UNUSED(itemKey);

    return nullptr;
}

测试插件加载

从源码构建

为了不污染源码目录,推荐在源码目录中创建build进行构建:

cd home_monitor
mkdir build
cd build
qmake ..
make -j4

安装

sudo make install

可以看到有home_monitor.so文件被安装在了 dde-dock 的插件目录。

install -m 755 -p ../../home_monitor/libhome_monitor.so /usr/lib/dde-dock/plugins/libhome_monitor.so

测试加载

执行pkill dde-dock; dde-dock来重新运行 dde-dock在终端输出中如果出现以下的输出说明插件的加载已经正常。

init plugin:  "home_monitor"
init plugin finished:  "home_monitor"

创建自己的 widget

按照一般的业务逻辑处理,这部分不是本教程的重点,可以参考完整代码及其它插件进行实现。

添加 widget 到 dde-dock 面板上

init方法中获取到了PluginProxyInterface对象,调用此对象的itemAdded即可实现向 dde-dock 面板上添加项目。 第二个QString类型的参数代表了本插件所提供的 item 的 id当一个插件提供多个 item 时,不同 item 之间的 id 要保证唯一。

proxyInter->itemAdded(this, QString());

在调用itemAdded之后dde-dock 会在合适的时机调用插件的itemWidget接口以获取需要显示的 widget。在 itemWidget 接口中分析 itemKey返回与之对应的 widget 对象当插件只有一个可显示项目时itemKey 可以忽略。

QWidget *HomeMonitorPlugin::itemWidget(const QString &itemKey)
{
    Q_UNUSED(itemKey);

    return m_pluginWidget;
}