☰
插件式框架学习(4)
2026/10/26 10:24:39 网站建设 项目流程

我确实有想过 "新增类也不用重新编译主程序"。我理解说,这相当于进一步的解耦合了。


是的,这会进一步把主程序和具体业务界面解耦。

当前的关系是:

主程序 ├── 容器与窗口工厂 └── C、D、E 的实现

主程序虽然通过名称选择内容,但仍包含这些类的实现,所以新增类需要重新编译主程序。


进一步可以变成:

主程序:加载 UI、提供容器、管理插件 统一接口:约定插件如何创建 QWidget 插件 A.dll:提供 C、D 插件 B.dll:提供 E 插件 F.dll:提供新界面 F

这样新增F的流程就是:

  1. 编写并单独编译F.dll。
  2. 放入程序的plugins目录。
  3. 在main.ui中把容器的contentClass设置为插件提供的名称。
  4. 重启程序,加载新界面。

主程序不用重新编译,新增的插件本身仍然需要编译。

我们已有插件加载器和窗口工厂,下一步可以把它们接起来:让插件通过统一接口提供“可创建的界面名称”和“创建 QWidget 的方法”,工厂再按名称调用对应插件。

还需要处理好一个生命周期约束:插件创建的窗口必须先销毁,才能卸载对应 DLL。同时保持 Qt、编译器和接口版本兼容,这套机制就能稳定扩展。


已实现:插件可以通过WidgetProvider接口声明并创建 QWidget,主程序自动注册这些类型。

示例ContentPlugin.dll提供:

  • plugin.f:计数面板
  • plugin.g:文本输入面板

容器的contentClass填对应名称即可加载。以后新增类只需编译插件 DLL,主程序不用重新编译。

修改左侧WidgetContainer:

重启软件:

我在思考一些事情:

这意味着我可以在ContentPlugin中创建100个子类QWidget,然后,

修改QWidget *ContentPlugin::createWidget(const QString &name, QWidget *parent),

就可以实现自由地加载子类了吗

对。你可以在ContentPlugin中实现 100 个QWidget子类,然后维护两处对应关系:

  1. widgetClasses():声明插件提供哪些名称。
  2. createWidget():根据名称创建对应的类。

例如:

QStringList ContentPlugin::widgetClasses() const { return {"panel.chart", "panel.device", "panel.settings"}; } QWidget *ContentPlugin::createWidget( const QString &name, QWidget *parent) { if (name == "panel.chart") return new ChartWidget(parent); if (name == "panel.device") return new DeviceWidget(parent); if (name == "panel.settings") return new SettingsWidget(parent); return nullptr; }

程序就会把ChartWidget装进去。

然后,在main.ui的容器中配置。

新增类后,只需重新编译并替换ContentPlugin.dll,再重启程序;主程序不用重新编译。已有类之间的选择则只需修改 UI。


Release v1.0.4:支持插件提供 QWidget,新增界面无需重编译主程序 · lianpeiliang/LearnFramework

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询