系列文章目录
提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
例如:CC For Windows源码编译
提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
CC
的软件框架和插件功能的开发是比较灵活的,该博文记录下插件的开发工作。插件分为三种,IO
, GL
和 Standard
,并没有细研究每种的区别,今天主要介绍下 Standard
类插件的开发。
一、基础
CC
是基于 QT
开发的,因此,在进行插件开发之前,需要适当的了解下 QT
相关的基础,其实也不需要太多,只要能掌控逻辑顺序和槽函数即可。
二、Example介绍
从 Example
推断运行机制,官网提供的 ExamplePlugin
中有四个文件,分别是:
ActionA.h
ActionA.cpp
ExamplePlugin.h
ExamplePlugin.cpp
其中,ExamplePlugin.*
是与 CC
的插件机制耦合的,一般情况是不需要改的,因为做插件的目的是为了扩展功能,如果要扩展的功能是独立的话,那就不需要改这俩文件了,ActionA.*
是具体的实现文件,可以简单的理解为,CC
的插件机制会调用 ExamplePlugin
,然后 ExamplePlugin
会出发 ActionA.*
中实现的功能,其触发指令为:
// EaxmplePlugin.cpp
// This method returns all the 'actions' your plugin can perform.
// getActions() will be called only once, when plugin is loaded.
QList<QAction*> ExamplePlugin::getActions()
{
// default action (if it has not been already created, this is the moment to do it)
if (!m_action)
{
// Here we use the default plugin name, description, and icon,
// but each action should have its own.
m_action = new QAction(getName(), this);
m_action->setToolTip(getDescription());
m_action->setIcon(getIcon());
// Connect appropriate signal
connect(m_action, &QAction::triggered, this, [this]()
{
Example::performActionA(m_app); // 触发 ActionA的功能函数
});
}
return { m_action };
}
执行功能的语句Example::performActionA(m_app);
三、具体实现
截止到此,CC
插件的开发就可以降维成 QT
组件开发了,在这里,介绍一个简单的弹出窗口(对于 CC
标准的插件流程可能不大适用,但是能实现功能,目前还不知道这样做的bug是啥)。
首先,在 ActionA.h
中新建个类,在这里,定义了一个叫 SegDialog
的类:
class SegDialog : public QDialog {
Q_OBJECT
public:
explicit SegDialog(ccMainAppInterface* appInterface = nullptr, QWidget* parent = nullptr);
~SegDialog() {};
private:
ccMainAppInterface* appInterface_;
}
注意看下构造函数和私有变量,有一个 ccMainAppInterfac
的变量,这个一定不能省略,这个类包含了界面显示的一些操作,比如,addDB, addPoint等,就是可以将你的展示结果显示在UI
界面上。
紧接着来看下实现:
// ActionA.cpp
SegDialog::SegDialog(ccMainAppInterface* appInterface, QWidget* parent)
: appInterface_(appInterface), QDialog(parent) {
}
只贴一下构造函数的实现就好了,至于里面怎么设计,完全可以随心所欲了。到了这里,是不是发现很熟悉了,通常在 QT
设计独立的弹窗的时候,也可以使用 Dialog
这个类。
介绍完功能的定义与实现了,再看下怎么触发:
void performActionA(ccMainAppInterface* appInterface)
{
SegDialog* pDlg = new SegDialog(appInterface);
pDlg->setMinimumSize(480, 640);
pDlg->setWindowTitle("Test Example");
pDlg->show();
}
看下,这个 performActionA
函数就是调用的入口, 在里面直接调用之前创建的 SegDialog
类就可以了。
四、附属文件介绍
ExamplePlugin
中有一个 info.json
的文件,里面存放了插件的部分信息,如下:
{
"type": "Standard", # 说明插件类型,不用管
"name": "Segmentation Example (Standard Plugin)", # 插件的名字,即在CC中的显示名字
"icon": ":/CC/plugin/ExamplePlugin/images/icon.png", # logo,在CC中该插件的log
"description": "This is a description of the marvelous Example plugin. It does nothing.",
"authors": [
{
"name": "Daniel Girardeau-Montaut",
"email": "daniel.girardeau@gmail.com"
}
],
"maintainers": [
{
"name": "Andy Maloney",
"email": "asmaloney@gmail.com"
},
{
"name": "Example NoEmail"
}
],
"references": [
{
"text": "The unsuccessful self-treatment of a case of “writer's block”",
"url": "https://www.ncbi.nlm.nih.gov/pmc/articles/PMC1311997/"
},
{
"text": "Sword swallowing and its side effects",
"url": "http://www.bmj.com/content/333/7582/1285"
},
{
"text": "I thought of creating this wonderful plugin while I was hiking up ⛰ Mont Blanc"
}
]
}
五、总结
看完介绍,是不是发现,其实 CC
插件的开发就是一个流程问题,而真正设计及核心的地方还是在 QT
的应用上。