peony 是优麒麟的文件管理器,我之前在 开源软件供应链点亮计划 活动中中选了实现预览插件的项目,今天稍微总结下。
可以先看看参考资料
下载编译 peony 和 peony-extensions
peony
sudo apt build-dep peony
这个装依赖我记得是不全的,编译时缺什么补什么吧
git clone https://github.com/ukui/peony.git
cd peony && mkdir build && cd build
qmake .. && make
sudo make install
在peony项目中,有一些关于插件测试的子项目,是项目早期为了进行验证的时候加上的,比如 https://github.com/ukui/peony/tree/master/peony-qt-plugin-test。可作为参考。
在 libpeony-qt / plugin-iface 中,定义了插件接口,比如 MenuPluginInterface,PreviewPagePluginIface,在实现插件时需要继承这些接口。
在 controls / preview-page 中实现的默认预览窗口就是继承 PreviewPagePluginIface 实现的。
plugin-manager.cpp 可以看到插件是如何加载的。
插件仓库
https://github.com/ukui/peony-extensions
同样下载编译好,不感兴趣的插件依赖没装好等原因不好编译的,在 peony-extensions.pro 注释它就行。
再次打开 peony,应该已经可以加载插件了。
已经写好的插件是很好的参考。
介绍一个简单插件
MenuPluginInterface,可以在右键菜单上添加功能项,应该是最常用的接口。
下面以设置壁纸的插件为例,当选中一个图片并右键呼出菜单时,会添加一个设置壁纸的选项。
- 在 peony-extensions.pro 中添加一个 SUBDIRS
- .pro 文件
QT += widgets
TARGET = peony-set-wallpaper
TEMPLATE = lib
DEFINES += PEONYSETWALLPAPER_LIBRARY
include(../common.pri)
CONFIG += debug link_pkgconfig plugin
PKGCONFIG += peony gsettings-qt
TRANSLATIONS = translations/peony-set-wallpaper-extension_zh_CN.ts \
translations/peony-set-wallpaper-extension_tr.ts
SOURCES += \
set-wallpaper-plugin.cpp
HEADERS += \
set-wallpaper-plugin.h \
peony-set-wallpaper_global.h
unix {
target.path = $$[QT_INSTALL_LIBS]/peony-extensions
INSTALLS += target
}
RESOURCES += \
peony-set-wallpaper.qrc
可以看到 include(../common.pri) 是规定了插件版本,如果 peony 版本与插件不一致,就会拒绝加载。这个和其他项目一致就行,不需要改。
PKGCONFIG += peony,可以使用 libpeony-dev 中的函数了。注意外部只能调用有PEONYCORESHARED_EXPORT 声明的类
- peony-set-wallpaper_global.h
#ifndef PEONYQTSETWALLPAPER_GLOBAL_H
#define PEONYQTSETWALLPAPER_GLOBAL_H
#include <QtCore/qglobal.h>
#if defined(PEONYSETWALLPAPER_LIBRARY)
# define PEONYQTSETWALLPAPERSHARED_EXPORT Q_DECL_EXPORT
#else
# define PEONYQTSETWALLPAPERSHARED_EXPORT Q_DECL_IMPORT
#endif
#endif // PEONYQTSETWALLPAPER_GLOBAL_H
即使没用过 Qt 插件体系,这些东西可以先照着抄,改改名字就行。
Q_DECL_EXPORT // 共享库项目
Q_DECL_IMPORT // 使用共享库的客户项目
这个 PEONYSETWALLPAPER_LIBRARY 在 .pro 中定义了。
- set-wallpaper-plugin.h
#ifndef SETWALLPAPERPLUGIN_H
#define SETWALLPAPERPLUGIN_H
#include "peony-set-wallpaper_global.h"
#include <menu-plugin-iface.h>
#include <QGSettings>
namespace Peony {
class PEONYQTSETWALLPAPERSHARED_EXPORT SetWallPaperPlugin: public QObject, public MenuPluginInterface
{
Q_OBJECT
Q_PLUGIN_METADATA(IID MenuPluginInterface_iid FILE "common.json")
Q_INTERFACES(Peony::MenuPluginInterface)
public:
explicit SetWallPaperPlugin(QObject *parent = nullptr);
PluginInterface::PluginType pluginType() override {return PluginInterface::MenuPlugin;}
const QString name() override {return tr("Peony-Qt set wallpaper Extension");}
const QString description() override {return tr("set wallpaper Extension.");}
const QIcon icon() override {return QIcon::fromTheme("");}
void setEnable(bool enable) override {m_enable = enable;}
bool isEnable() override {return m_enable;}
QString testPlugin() override {return "test set wallpaper";}
QList<QAction *> menuActions(Types types, const QString &uri, const QStringList &selectionUris) override;
bool is_picture_file(QString file_name);
private:
bool m_enable;
QStringList m_picture_type_list = {"png", "jpg", "jpeg", "bmp", "dib", "jfif", "jpe", "gif", "tif", "tiff", "wdp"};
QGSettings *m_bg_settings = nullptr;
};
}
#endif // SETWALLPAPERPLUGIN_H
这里面插件机制相关的代码,就是换个名字的事,各个插件都是类似的。
重载自 MenuPluginInterface 的 QList<QAction *> menuActions(Types types, const QString &uri, const QStringList &selectionUris) 是实现功能的关键。
QList<QAction*> SetWallPaperPlugin::menuActions(Types types, const QString &uri, const QStringList &selectionUris)
{
QList<QAction*> actions;
if (types == MenuPluginInterface::DirectoryView || types == MenuPluginInterface::DesktopWindow)
{
if (selectionUris.count() == 1 && is_picture_file(selectionUris.first())) {
if (selectionUris.first().contains("trash:///"))
return actions;
QAction *set_action = new QAction(tr("Set as wallpaper"), nullptr);
actions<<set_action;
connect(set_action, &QAction::triggered, [=](){
if (QGSettings::isSchemaInstalled(BACKGROUND_SETTINGS))
{
m_bg_settings = new QGSettings(BACKGROUND_SETTINGS, QByteArray(), this);
QUrl url= selectionUris.first();
bool success = m_bg_settings->trySet("pictureFilename", url.path());
qDebug() << "set as wallpaper result:" <<success <<url.path();
}
});
}
}
return actions;
}
其他类型的插件也是类似的,实现相应接口即可。
这个是我在实现预览插件时的笔记:
https://zany-yoke-295.notion.site/Peony-07be443c7e314f17b021056c380ccaaa