• [CC]CC插件初探


    应用程序插件框架的内容包括:主程序App,插件Plugin。

    1、实现一个应用程序插架框架关键点有:

    一个插件的标准接口,在主程序中存在一个插件的集合。主程序通过循环读取每个插件,将插件对象通过多态的机制转换为插件接口,实现插件的装载。

    主程序对象或者主程序接口需要作为参数传递到插件对象中,以方便插件对象调用主程序的内容,如主视图、工具栏、树视图、状态栏等。

    2、开源点云处理软件CloudCompare也是一个插件框架,因此也必然包括这些内容。

      插件接口:ccPluginInterface,每个插件对象有在ccPluginInterface基础上定义了一个新的接口类class ccStdPluginInterface : public ccPluginInterface

          具体的插件则继承自ccStdPluginInterface 累,比如这样,class qMyPlugin : public QObject, public ccStdPluginInterface

      主程序对象:class ccMainAppInterface,MainWindow主窗体类实现了ccMainAppInterface接口。

          MainWindow::loadPlugins()方法负责插件的调用。(mainwindow.cpp文件中)

     1 void MainWindow::loadPlugins()
     2 {
     3     menuPlugins->setEnabled(false);
     4     menuShadersAndFilters->setEnabled(false);
     5     toolBarPluginTools->setVisible(false);
     6     toolBarGLFilters->setVisible(false);
     7 
     8     //"static" plugins
     9     foreach (QObject *plugin, QPluginLoader::staticInstances())
    10         dispatchPlugin(plugin);
    11 
    12     ccConsole::Print(QString("Application path: ")+QCoreApplication::applicationDirPath());
    13 
    14 #if defined(Q_OS_MAC)
    15     // plugins are in the bundle
    16     QString path = QCoreApplication::applicationDirPath();
    17     path.remove( "MacOS" );
    18     m_pluginsPath = path + "Plugins/ccPlugins";
    19 #else
    20     //plugins are in bin/plugins
    21     m_pluginsPath = QCoreApplication::applicationDirPath()+QString("/plugins");
    22 #endif
    23 
    24     ccConsole::Print(QString("Plugins lookup dir.: %1").arg(m_pluginsPath));
    25 
    26     QStringList filters;
    27 #if defined(Q_OS_WIN)
    28     filters << "*.dll";
    29 #elif defined(Q_OS_LINUX)
    30     filters << "*.so";
    31 #elif defined(Q_OS_MAC)
    32     filters << "*.dylib";
    33 #endif
    34     QDir pluginsDir(m_pluginsPath);
    35     pluginsDir.setNameFilters(filters);
    36     foreach (QString filename, pluginsDir.entryList(filters))
    37     {
    38         QPluginLoader loader(pluginsDir.absoluteFilePath(filename));
    39         QObject* plugin = loader.instance();
    40         if (plugin)
    41         {
    42             ccConsole::Print(QString("Found new plugin: '%1'").arg(filename));
    43             if (dispatchPlugin(plugin))
    44             {
    45                 m_pluginFileNames += filename;
    46             }
    47             else
    48             {
    49                 delete plugin;
    50                 plugin = 0;
    51                 ccConsole::Warning("	Unsupported or invalid plugin type");
    52             }
    53         }
    54         else
    55         {
    56             delete plugin;
    57             plugin = 0;
    58             ccConsole::Warning(QString("[Plugin] %1")/*.arg(pluginsDir.absoluteFilePath(filename))*/.arg(loader.errorString()));
    59         }
    60     }
    61 
    62     if (menuPlugins)
    63     {
    64         menuPlugins->setEnabled(!m_stdPlugins.empty());
    65     }
    66 
    67     if (toolBarPluginTools->isEnabled())
    68     {
    69         actionDisplayPluginTools->setEnabled(true);
    70         actionDisplayPluginTools->setChecked(true);
    71     }
    72     else
    73     {
    74         //DGM: doesn't work :(
    75         //actionDisplayPluginTools->setChecked(false);
    76     }
    77 
    78     if (toolBarGLFilters->isEnabled())
    79     {
    80         actionDisplayGLFiltersTools->setEnabled(true);
    81         actionDisplayGLFiltersTools->setChecked(true);
    82     }
    83     else
    84     {
    85         //DGM: doesn't work :(
    86         //actionDisplayGLFiltersTools->setChecked(false);
    87     }
    88 }

          主程序在加载插件时会调用插件的setMainAppInterface方法,将主程序参数传入,这样插件就可以获取主程序的内容了。

    1 //! Sets application entry point
    2 /** Called just after plugin creation by qCC
    3 **/
    4 virtual void setMainAppInterface(ccMainAppInterface* app);

    3、获取主窗体中的点云图层

    在doAction中的代码:

     1     const ccHObject::Container& selectedEntities = m_app->getSelectedEntities();
     2     size_t selNum = selectedEntities.size();
     3     if (selNum!=1)
     4     {
     5         m_app->dispToConsole("Select only one cloud!",ccMainAppInterface::ERR_CONSOLE_MESSAGE);
     6         return;
     7     }
     8 
     9     ccHObject* ent = selectedEntities[0];
    10     assert(ent);
    11     if (!ent || !ent->isA(CC_TYPES::POINT_CLOUD))
    12     {
    13         m_app->dispToConsole("Select a real point cloud!",ccMainAppInterface::ERR_CONSOLE_MESSAGE);
    14         return;
    15     }
    16 
    17     ccPointCloud* pc = static_cast<ccPointCloud*>(ent);
    18 
    19     //input cloud
    20     unsigned count = pc->size();
    21     bool hasNorms = pc->hasNormals();
    22     CCVector3 bbMin, bbMax;
    23     pc->getBoundingBox(bbMin,bbMax);
    24     const CCVector3d& globalShift = pc->getGlobalShift();
    25     double globalScale = pc->getGlobalScale();    
  • 相关阅读:
    C# winform 学习(一)
    C# winform 学习(一)
    C# winform 学习(二)
    C# winform 学习(二)
    C# Winform 学习(四)
    C# Winform 学习(四)
    C# winform 学习(三)
    gcc编译动态和静态链接库
    对深拷贝与浅拷贝的再次理解(默认构造函数是浅拷贝)
    QWaitCondition(和Java的Notify机制非常相像)
  • 原文地址:https://www.cnblogs.com/yhlx125/p/5425040.html
Copyright © 2020-2023  润新知