IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> QgisPlugin插件开发技术 -> 正文阅读

[游戏开发]QgisPlugin插件开发技术

简介

QGIS的插件框架,结构简单、效果明显。基于插件技术,划分出各个相互独立的模块,可灵活搭建界面和组件库,在协作开发、版本迭代、功能扩展等多个层面都有很好的敏捷性。

插件类型

插件类型定义在QgsPlugin类中,包括UI插件、图层插件、渲染插件三种类型。插件类通过QgisInterface接口,进行模块之间的交互。

enum PluginType
    {
      UI = 1,   //!< User interface plug-in
      MapLayer, //!< Map layer plug-in
      Renderer, //!< A plugin for a new renderer class
    };

插件元数据类

QgsPluginMetadata,用于记录插件的名称、版本、类型、描述等基本信息,以及插件类的指针对象。

插件注册与加载

在QGIS中,插件注册的本质是把插件的名称和元数据类存储在QMap<QString, QgsPluginMetadata>对象中。
在这里插入图片描述看一下注册插件的核心代码(省略掉不重要代码,关键是理解注册机制):

void QgsPluginRegistry::loadCppPlugin( const QString &fullPathName )
{
  //....省略掉一段源码
  QLibrary myLib( fullPathName );
  bool loaded = myLib.load();
  //...省略掉一段源码
  //type就是定义的插件类型
  type_t *pType = ( type_t * ) cast_to_fptr( myLib.resolve( "type" ) );
  name_t *pName = ( name_t * ) cast_to_fptr( myLib.resolve( "name" ) );
  switch ( pType() )
  {
    case QgisPlugin::Renderer:
    case QgisPlugin::UI:
    {
      // UI only -- doesn't use mapcanvas
      create_ui *cf = ( create_ui * ) cast_to_fptr( myLib.resolve( "classFactory" ) );
      if ( cf )
      {
        QgisPlugin *pl = cf( mQgisInterface );
        if ( pl )
        {
          //往主界面中添加插件的UI,在应用中可以通过实现自己的qgisinterface来控制UI的添加方式
          pl->initGui();
          // add it to the plugin registry
          addPlugin( baseName, QgsPluginMetadata( myLib.fileName(), pName(), pl ) );
          //...省略掉一段源码
      }
      //...省略掉一段源码
    }
    break;
    default://...省略掉一段源码
  }
}

加载插件的代码是在QgisApp类构造函数中调用的:

QgsPluginRegistry::instance()->setQgisInterface( mQgisInterface );
if ( restorePlugins )
{
    // Restoring of plugins can be disabled with --noplugins command line option
    // because some plugins may cause QGIS to crash during startup
    QgsPluginRegistry::instance()->restoreSessionPlugins( QgsApplication::pluginPath() );
    // Also restore plugins from user specified plugin directories
    QString myPaths = settings.value( QStringLiteral( "plugins/searchPathsForPlugins" ), "" ).toString();
    if ( !myPaths.isEmpty() )
    {
      QStringList myPathList = myPaths.split( '|' );
      QgsPluginRegistry::instance()->restoreSessionPlugins( myPathList );
    }
}

当然,在加载插件之前还要对插件的合法性进行验证,代码如下:

bool QgsPluginRegistry::checkCppPlugin( const QString &pluginFullPath )
{
  QLibrary myLib( pluginFullPath );
  bool loaded = myLib.load();
  if ( ! loaded )
  {
    QgsMessageLog::logMessage( QObject::tr( "Failed to load %1 (Reason: %2)" ).arg( myLib.fileName(), myLib.errorString() ), QObject::tr( "Plugins" ) );
    return false;
  }
  name_t *myName = ( name_t * ) cast_to_fptr( myLib.resolve( "name" ) );
  description_t   *myDescription = ( description_t * )  cast_to_fptr( myLib.resolve( "description" ) );
  category_t   *myCategory = ( category_t * )  cast_to_fptr( myLib.resolve( "category" ) );
  version_t   *myVersion = ( version_t * ) cast_to_fptr( myLib.resolve( "version" ) );
  if ( myName && myDescription && myVersion  && myCategory )
    return true;
  QgsDebugMsgLevel( "Failed to get name, description, category or type for " + myLib.fileName(), 2 );
  return false;
}

QGIS插件的存放路径一般是运行时的plugins文件夹中,也可以通过环境变量配置默认的插件路径。从下图中,大致可以看出:名称以plugin结尾的是UI类型的插件;以provider结尾的都是图层类型的插件,用于各类数据格式的读写等。
在这里插入图片描述

扩展插件的实现

这里只介绍以plugin结尾的UI插件,以拓扑检查的插件topolplugin.dll为例。
插件类要继承QObject, QgisPlugin这两个类,且必须实现initGui()虚函数,其他自定义的函数用于配合实现UI的逻辑。

static const QString sName = QObject::tr( "Topology Checker" );
static const QString sDescription = QObject::tr( "A Plugin for finding topological errors in vector layers" );
static const QString sCategory = QObject::tr( "Vector" );
static const QString sPluginVersion = QObject::tr( "Version 0.1" );
static const QgisPlugin::PluginType sPluginType = QgisPlugin::UI;
static const QString sPluginIcon = QStringLiteral( ":/topology/mActionTopologyChecker.svg" );
class Topol: public QObject, public QgisPlugin
{
    Q_OBJECT
  public:
    explicit Topol( QgisInterface *interface );
  public slots:
    //! init the gui
    void initGui() override;
    //! Create and show the dialog box
    void run();
    //! Show/hide the dialog box
    void showOrHide();
    //! unload the plugin
    void unload() override;
    //! show the help document
    void help();
  private:
    QgisInterface *mQGisIface = nullptr;
    //!pointer to the qaction for this plugin
    QAction *mQActionPointer = nullptr;
    checkDock *mDock = nullptr;
};

再来看initGui()的定义:

void Topol::initGui()
{
  delete mQActionPointer;//为什么可以直接删除指针?
  mQActionPointer = new QAction( QIcon( sPluginIcon ), sName, this );
  mQActionPointer->setObjectName( QStringLiteral( "mQActionPointer" ) );
  mQActionPointer->setCheckable( true );
  mQActionPointer->setWhatsThis( tr( "Topology Checker for vector layer" ) );
  // 绑定ui控件与执行函数
  connect( mQActionPointer, &QAction::triggered, this, &Topol::showOrHide );
  // 在qgisInterface中添加ui
  //qgisInterface是虚类,具体的实现由QgisApp类实现
  mQGisIface->addVectorToolBarIcon( mQActionPointer );
  mQGisIface->addPluginToVectorMenu( QString(), mQActionPointer );
}

再来看QgisApp类对添加UI控件的实现:

void QgisApp::addPluginToVectorMenu( const QString &name, QAction *action )
{
  QMenu *menu = getVectorMenu( name );
  menu->addAction( action );
}

这既是实现插件的开发过程,对照前面定义的目录是Vector,名称是Topology Checker,即可在工具栏中找到该控件。

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-09-30 12:15:25  更:2021-09-30 12:16:40 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/28 3:42:55-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码