面向开发者:插件框架、宿主程序启动流程、功能页开发流程与构建调试要点。
使用者请阅读 HugoWidgets 用户文档。
| 项 | 内容 |
|---|---|
| 语言 / 标准 | C++,CONFIG += c++2b |
| UI 框架 | Qt6 |
| 构建系统 | qmake |
| 插件框架 | WidgetExplorer |
| 核心能力库 | HugoUtils(含 WinUtils) |
当前采用 WidgetExplorer 的旧版框架,便捷性有限,但暂时不会升级到新版本。
HugoWidgets/
├── WidgetExplorer.pro # 顶层 qmake 工程(SUBDIRS)
├── README.md
├── docs/ # 文档
├── icons/ # 图标
├── licenses/ # 第三方许可证副本
├── deps/ # 依赖库
├── src/
│ ├── WidgetExplorer.pro # 宿主程序工程
└── plugins/
├── HugoMain/ # 主界面插件
│ ├── HugoMain.pro
│ ├── hugomainplugin.h/.cpp # WPlugin 实现
│ ├── hugomainwidget.h/.cpp # 主窗口(菜单栏 + 标签页)
│ ├── IHugoMain.h # 事件/键名常量
│ └── functionpagebase.h # 功能页基类(插件间共享接口)
└── HugoWidgetsPlugin/ # 功能页插件
├── HugoWidgetsPlugin.pro
├── HugoWidgetsPlugin.h/.cpp
└── HugoPages/ # 功能页
- Qt6
- Git(拉取子模块)
git clone https://github.com/HugoWidget/HugoWidgets --recursive用 Qt Creator 打开顶层 WidgetExplorer.pro
HugoMain 负责「壳」:菜单栏、标签页与功能页的装载。
HugoMainPlugin::init 做了三件事:
-
WinUtils::Console console; console.attach();—— 附加控制台,便于查看底层库输出(调试友好)。 -
创建并注册主窗口:
widget = new HugoMainWidget(PData); widgetManager->addWidget(QUuid::createUuid(), widget, this);
-
解析命令行参数并立即执行命令。
HugoMainWidget 是 QWidget,内部持有一个 QMainWindow 与一个 QTabWidget。
IHugoMain.h 定义了事件与键名常量:
| 类别 | 常量 |
|---|---|
Event |
MenuAction、ToolAction、Tab |
Key |
MenuPath、TabTitle |
functionpagebase.h 是功能页插件与主界面之间的契约,位于 HugoMain 目录但被两个插件共同引用(在 HugoWidgetsPlugin.pro 的 HEADERS 中以 ../HugoMain/FunctionPageBase.h 形式加入)。
开发新功能页时必须实现 id()、name()、handleCommand()。
HugoWidgetsPlugin::init 在设置元数据后,把 5 个功能页交给主界面:
auto createPage = [&](FunctionPageBase* base) {
WMessage msg2;
msg2.object = base;
WEvent extEvent(QString("hugo.hugowidget.hugowidgets.addpage"), msg2);
widgetManager->publish(extEvent);
};
createPage(new HugoXxxPage);要点:
- 通过
hugo.hugowidget.hugowidgets.addpage事件发布功能页,由主界面插件接收并登记(加入m_allPagesById、在主页与菜单栏呈现入口)。这就是功能页插件与主界面解耦的关键。 - 功能页对象以裸指针创建,生命周期由接收方(主界面)管理,页面关闭时调用
cleanup()。
-
在
plugins/HugoWidgetsPlugin/HugoPages/下新建HugoXxxPage.h/.cpp(需要界面时可加.ui)。 -
继承
FunctionPageBase,实现三个纯虚函数:class HugoXxxPage : public FunctionPageBase { Q_OBJECT public: explicit HugoXxxPage(QWidget *parent = nullptr); ~HugoXxxPage() override; QString id() const override; // 唯一 id QString name() const override; // 显示名称 bool handleCommand(const QString &command, const QVariantMap &args = QVariantMap()) override; void init() override; // 可选:打开页面时初始化 void cleanup() override; // 可选:关闭页面时清理 private slots: void on_m_btnDo_clicked(); };
-
把新文件加入 HugoWidgetsPlugin.pro。
-
在
HugoWidgetsPlugin::init()中追加createPage(new HugoXxxPage);。 -
重新构建插件——功能入口会自动出现在主页与菜单栏(由主界面根据
id()/name()生成)。
- 在
plugins/下新建目录,参照 HugoMain.pro 编写.pro(TEMPLATE = lib、CONFIG += plugin、DESTDIR指向src/<cfg>/plugins/HugoWidget、includeWECore / HugoUtils 的.pri)。 - 实现
WPlugin的init/recMsg/deinit,在init中用PluginData::setData/setPlugin取回框架对象并setMetaData设置插件名与作者。 - 把新插件加入顶层 WidgetExplorer.pro 的
SUBDIRS(注意CONFIG += ordered,插件应排在src/WidgetExplorer.pro之后)。 - 在插件清单中登记:在元数据里为其分配数字键,并填写
Plugin::Path等字段,否则不会被加载。 - 构建后在程序目录验证:插件能被加载且在插件列表/主界面选择对话框中可见。