NEWS

新闻

了解openKylin最新资讯,关注社区和产品动态。

NEWS

Learn about the latest news.

【小白课程】UKUI快捷面板插件开发指南

2024-07-22 14:13:48

在openKylin UKUI 4.10版本中,快捷操作窗口可从任务栏托盘中点击唤起,并默认显示在桌面右下角。

openKylin(开放麒麟)

目前快捷操作包含以下三种样式:可展开菜单按钮样式、图标样式、进度条样式。现有的功能和对应显示形式如下表所示:

按钮样式功能
可展开菜单按钮样式无线网络网络链接
图标样式模式切换、自动旋转、飞行模式、多屏显示
系统设置、省电模式、夜间模式、冰冻模式
进度条样式亮度调节、音量调节

下面我们将重点介绍如何实现一个自定义插件。

一、插件接口介绍


UKUI 4.10快捷操作源码地址:

https://gitee.com/openkylin/ukui-sidebar

其中,ukui-shortcut模块提供了一个用于开发自定义功能的插件接口,我们需要关注path to src/ukui-sidebar/ukui-shortcut/interface中的文件:

openKylin(开放麒麟)

为了实现一个自定义插件,需要继承其中的UkuiShortcutPlugin类和Shortcut类。

1.UkuiShortcutPlugin

基于QtPlugin机制,UkuiShortcutPlugin类定义了插件需要实现的标准接口:

    #define UKUI_SHORTCUT_PLUGIN_IFACE_IID "org.ukui.shortcut.UkuiShortcutPluginIface"#define UKUI_SHORTCUT_PLUGIN_IFACE_TYPE "UKUI_SHORT_CUT"#define UKUI_SHORTCUT_PLUGIN_IFACE_VERSION "1.0.1"
    class UkuiShortcutPlugin : public QObject{Q_OBJECTpublic:explicit UkuiShortcutPlugin(QObject *parent = nullptr);~UkuiShortcutPlugin() override;
    /** 插件id,需要确保唯一*/virtual QString pluginId() = 0;/*** 快捷按钮的翻译文件名称* eg: 自动旋转按钮的翻译文件:auto-rotation-shortcut_zh_CN.qm,* 那么此方法只需要返回 "auto-rotation-shortcut" 即可。* 翻译文件会在插件被加载前加载。** @return 可以返回多个翻译文件名称*/virtual QStringList translations() = 0;/*** 创建快捷按钮,用于实例化一个继承自(Shortcut)的快捷操作类* @return Shortcut**/virtual Shortcut *createShortcut() = 0;};Q_DECLARE_INTERFACE(UkuiShortcut::UkuiShortcutPlugin, UKUI_SHORTCUT_PLUGIN_IFACE_IID)

    2. Shortcut

    Shortcut类定义了快捷键的类型、操作、是否启用、当前状态信息等接口:

      class UKUISHORTCUT_EXPORT Shortcut : public QObject{Q_OBJECTpublic:explicit Shortcut(QObject *parent = nullptr) : QObject(parent) {}/*** 插件id, 同UkuiShortcutPlugin中的pluginId*/virtual QString pluginId() = 0;/*** 插件类型(样式), 需要指定不同模式下的按钮元数据。* PluginMetaType::SystemMode表示不同的系统模式,* 目前支持pc(SystemMode::PC)和平板(SystemMode::Tablet)两种*/virtual QMap<PluginMetaType::SystemMode, PluginMetaData> pluginMetaData() = 0;/*** 实现响应前端用户操作*/virtual void active(PluginMetaType::Action action) = 0;/*** 进度条样式需要实现该函数*/virtual void setValue(int value) {Q_UNUSED(value)}/*** 返回插件当前的状态信息*/virtual const StatusInfo currentStatus() = 0;/*** 是否启用此插件*/virtual bool isEnable() { return true; }

      Q_SIGNALS:/*** 状态更新时发送*/void statusChanged(const StatusInfo &info);/*** 启用状态更新*/void enableStatusChanged(bool isEnable);};

      需要注意的是,请尽量不要在主线程中进行耗时操作,如进程间通信,文件读写等,避免造成UI卡顿。
      PluginMetaData类中可以定义快捷键的按钮样式(PluginMetaType::PluginType)、排列顺序(index)、显示状态(visible)等。PluginMetaData中的visible表示对应的系统模式下按钮是否显示。快捷面板的按钮样式(PluginType)有Icon、ProgressBar、MenuButton 三种;在UI上对应的显示区域中其排列顺序按照index递增,index为-1时会放在最后。当用户执行操作时,插件的active()函数会被调用,PluginMetaType::Action用于区分不同的操作类型,支持Click(点击)、LongClick(长按)、MenuRequest(请求菜单)三种操作。
      StatusInfo类用于存放插件的UI状态数据,包括按钮颜色、名称、图标、工具提示、是否置灰、菜单(可展开菜单按钮样式)、value值(进度条样式),前端会根据获取到的状态信息实时更新UI。
      二、插件自定义实现示例


      接下来我们将举例实现一个按钮类型的插件,功能为点击即打开默认浏览器访问B站。

      1.构建

      以cmake为例,需要在CMakeList.txt中增加

        find_package(ukui-shortcut REQUIREDtarget_link_libraries(${PROJECT_NAME} PRIVATE ukui-shortcut)

        2.代码实现

        首先我们继承Shortcut类实现按钮的主要功能:

          #include <QObject>#include "ukui-shortcut-plugin.h"

          class BiliBiliShortcut : public Shortcut{Q_OBJECTpublic:explicit BiliBiliShortcut(QObject *parent = nullptr);~BiliBiliShortcut() override;

          QString pluginId() override;QMap<PluginMetaType::SystemMode, PluginMetaData> pluginMetaData() override;void active(PluginMetaType::Action action) override;const StatusInfo currentStatus() override;bool isEnable() override;

          private:void trigger();inline void initMetaData();

          bool m_isEnable = false;StatusInfo m_currentStatusInfo;QMap<PluginMetaType::SystemMode, PluginMetaData> m_metaData;};

          可以在构造函数中定义插件按钮的状态信息和插件类型,并且通过currentStatus()返回。在此我们定义了一个在PC模式和平板模式均为图标样式的快捷按钮:

            BiliBiliShortcut::BiliBiliShortcut(QObject *parent) : Shortcut(parent){m_currentStatusInfo.setColor(Color::ColorRole::BaseColor);//当前状态信息初始化m_currentStatusInfo.setName(tr("bilibili"));m_currentStatusInfo.setIcon("qrc:///bilibili.svg");m_currentStatusInfo.setToolTip(tr("bilibili"));m_isEnable = true;
            initMetaData();}
            ... ...
            void BiliBiliShortcut::initMetaData(){// 在PC模式和平板模式均为图标样式的快捷按钮PluginMetaData pc {true, -1, PluginMetaType::PluginType::Icon};PluginMetaData tablet {true, -1, PluginMetaType::PluginType::Icon};m_metaData.insert(PluginMetaType::SystemMode::PC, pc);m_metaData.insert(PluginMetaType::SystemMode::Tablet, tablet);}在active()函数中根据不同PluginMetaType::Action执行对应函数,以下是当事件为Click时,执行打开B站的操作:void ControlCenterShortcut::active(PluginMetaType::Action action){if (action == PluginMetaType::Action::Click) {//在此打开B站QDesktopServices::openUrl(QUrl("https://www.bilibili.com/", QUrl::TolerantMode));}}

            接下来继承UkuiShortcutPlugin并实现对应接口:

              #include <QObject>#include "ukui-shortcut-plugin.h"

              class BiliBiliShortcutPlugin : public UkuiShortcutPlugin{Q_OBJECTQ_PLUGIN_METADATA(IID UKUI_SHORTCUT_PLUGIN_IFACE_IID FILE "bilibili-shortcut.json") // TODOQ_INTERFACES(UkuiShortcut::UkuiShortcutPlugin)public:explicit BiliBiliShortcutPlugin(QObject *parent = nullptr);

              QString pluginId() override { return QStringLiteral("bilibili"); };QStringList translations() override;Shortcut *createShortcut() override;};
              在头文件中需要用Q_INTERFACES宏来声明接口类,并且传入插件的抽象接口类名称(UkuiShortcut::UkuiShortcutPlugin)。

              Q_PLUGIN_METADATA声明自定义插件的元数据信息,FILE是可选的,并指向一个json文件,其中包含插件的类型信息和版本信息,其中版本信息需要和UKUI_SHORTCUT_PLUGIN_IFACE_VERSION宏一致:

                { "Type": "UKUI_SHORT_CUT", "Version": "1.0.1"}
                好了,到这一步,我们的自定义插件功能就完成啦!接下来我们需要将插件安装到对应的系统目录下:
                  # 插件安装目录set(PLUGIN_INSTALL_DIRS "/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}/ukui-shortcut-plugins")# 插件翻译文件安装目录set(SHORTCUT_TRANSLATION_FILE_DIR "/usr/share/ukui-sidebar/shortcuts/translations")# 安装.so和翻译文件install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION "${PLUGIN_INSTALL_DIRS}")install(FILES ${QM_FILES} DESTINATION "${TRANSLATION_FILE_DIR}")

                  编译安装后,注销再登陆,我们的自定义插件功能就已经被加载到快捷面板中啦!各位小伙伴你学会了嘛?
                  openKylin(开放麒麟)

                  最后,附上示例插件demo源码,地址如下:

                  https://gitee.com/qiqi49/shortcut-plugin-test