QGIS プロバイダプラグインその3:プロバイダプラグインを呼び出すGUIプラグインを作成

プロバイダプラグインは、単独ではQGIS側から呼び出す仕組みはありません。
なので、ここではデバッグを行えるようにするために、プロバイダプラグイン呼び出し専用GUIプラグインを作成します。

とりあえずプラグイン用の空プロジェクトを作成します。
ここでは、プロジェクトの名称は「compass_survey_plugin」としました。

プラグイン起動時のダイアログ作成

まず、Qt Creatorを起動し、[ファイル]メニューから[ファイル/プロジェクトの新規作成]を選択します。

ファイル/プロジェクトの新規作成メニュー

新規作成ダイアログから、”Qtデザイナフォーム”を選択します。

Qtデザイナフォームを選択

フォームテンプレートを選択します。3つのダイアログの中からどれかを選択します。

フォームテンプレートを選択

最後にuiファイルを保存する場所を指定します。
ここでは、「compass_survey_plugin.ui」という名前で保存します。

保存先を指定

フォームデザイナが起動するので、ダイアログを適当にデザインします。
ダイアログオブジェクトの名称の設定は後でそのままクラス名になるので、必ず設定します。
ここでは、他のQGISプラグインをまねて、「QgsCompassSurveyPluginBase」としました。
その他のコントロールも適宜名称を設定します。

ダイアログ作成

作成したら、コマンドプロンプトから以下のコマンドを実行します。
-oオプションは出力ファイルの名称です。
ここでも他のプラグインの名称をまねています。

> uic -o ui_compass_survey_plugin.h compass_survey_plugin.ui

ヘッダファイルができていることを確認し、できたファイルを上記の空プロジェクトに追加します。

Pluginクラスの作成

プラグインのクラスを作成します。必要なクラスは2つあります。
まず、プラグインのクラスを作成します。
ここではクラス名は「QgsCompassSurveyPlugin」、「QgsCompassSurveyPluginGui」とします。
とりあえず基底クラスは無しで作成します。

クラスを作成したら、プラグイン用にあれこれコードを追加していきます。まず、ヘッダファイルは以下のようにします。

QgsCompassSurveyPlugin.h

   1: #pragma once
   2: #include "qobject.h"
   3: #include "qgisplugin.h"
   4: #include "ui_compass_survey_plugin.h"
   5: 
   6: #ifndef QGISEXTERN
   7: #ifdef WIN32
   8: #  define QGISEXTERN extern "C" __declspec( dllexport )
   9: #  ifdef _MSC_VER
  10: // do not warn about C bindings returning QString
  11: #    pragma warning(disable:4190)
  12: #  endif
  13: #else
  14: #  define QGISEXTERN extern "C"
  15: #endif
  16: #endif
  17: 
  18: #ifndef PLUGIN
  19: #define PLUGIN
  20: 
  21: class QgisInterface;
  22: 
  23: class QgsCompassSurveyPlugin :
  24: 	public QObject, public QgisPlugin, private Ui::QgsCompassSurveyPluginBase
  25: {
  26:   Q_OBJECT
  27: 
  28: public:
  29: 	QgsCompassSurveyPlugin( QgisInterface * );
  30: 	~QgsCompassSurveyPlugin(void);
  31: 
  32: 	virtual QString name();
  33: 	virtual QString version();
  34: 	virtual QString description();
  35: 	virtual int type();
  36: 	virtual void initGui();
  37: 	void unload();
  38: 
  39: private:
  40: 	QgisInterface *qGisInterface;
  41: 	QAction *mAction;
  42: 	QString pluginNameQString;
  43: 	QString pluginVersionQString;
  44: 	QString pluginDescriptionQString;
  45: 
  46: private slots:
  47: 	void run();
  48: };
  49: 
  50: #endif

QgsCompassSurveyPluginクラスは3つのクラスを多重継承します。
VC2008のクラス作成画面では基底クラスは1つしか指定できない(たぶん??)ので、
とりあえず基底クラス無しで作成してから後でこのように追加します。

QgsCompassSurveyPluginGui.h

   1: #pragma once
   2: 
   3: #include "ui_compass_survey_plugin.h"
   4: 
   5: class QgisInterface;
   6: 
   7: class QgsCompassSurveyPluginGui : public QDialog, private Ui::QgsCompassSurveyPluginBase
   8: {
   9: 	Q_OBJECT
  10: 
  11: public:
  12: 	QgsCompassSurveyPluginGui( QgisInterface * _qI, QWidget * parent, Qt::WFlags fl );
  13: 	~QgsCompassSurveyPluginGui(void);
  14: 
  15: private slots:
  16: 	void on_buttonBox_accepted();
  17: 	void on_buttonBox_rejected();
  18: 	void OnBtnBrowse_clicked();
  19: 
  20: private:
  21: 	QgisInterface * qI;
  22: };

ダイアログの「参照」ボタンはファイルブラウザを起動するボタンで、18行目にボタンを押したときのスロットを宣言しています。
これに合わせて、uicコマンドで作成したui_compass_survey_plugin.hにシグナル/スロット接続を追加します。

ui_compass_survey_plugin.h setupUi()関数内追加部分

  QObject::connect(btnBrowse, SIGNAL(clicked()), QgsCompassSurveyPluginBase, SLOT(OnBtnBrowse_clicked()));

cppファイルのほうも上記のヘッダに合わせて関数の定義を書き込んでいきます。
以下の例はとりあえず最低限の実装を施したものです。

QgsCompassSurveyPlugin.cpp

   1: #include "qgisinterface.h"
   2: #include "QgsCompassSurveyPlugin.h"
   3: #include "QgsCompassSurveyPluginGui.h"
   4: #include "qgisgui.h"
   5: #include <QAction>
   6: 
   7: static const QString pluginVersion = QObject::tr( "Version 0.1" );
   8: static const QString description_ = QObject::tr( "Load Compass Survey data" );
   9: 
  10: QgsCompassSurveyPlugin::QgsCompassSurveyPlugin( QgisInterface * theQgisInterFace )
  11:     : qGisInterface( theQgisInterFace )
  12: {
  13: 	pluginNameQString = tr( "CompassSurveyDataLayer" );
  14: 	pluginVersionQString = pluginVersion;
  15: 	pluginDescriptionQString = description_;
  16: }
  17: 
  18: QgsCompassSurveyPlugin::~QgsCompassSurveyPlugin(void)
  19: {
  20: }
  21: 
  22: QString QgsCompassSurveyPlugin::name()
  23: {
  24: 	return pluginNameQString;
  25: }
  26: 
  27: 
  28: QString QgsCompassSurveyPlugin::version()
  29: {
  30: 	return pluginVersionQString;
  31: 
  32: }
  33: 
  34: QString QgsCompassSurveyPlugin::description()
  35: {
  36: 	return pluginDescriptionQString;
  37: }
  38: 
  39: int QgsCompassSurveyPlugin::type()
  40: {
  41: 	return QgisPlugin::UI;
  42: }
  43: 
  44: void QgsCompassSurveyPlugin::initGui()
  45: {
  46: 	mAction = new QAction( tr( "Add compass survey data layer" ), this );
  47: 	connect( mAction, SIGNAL(activated()), this, SLOT(run()) );
  48: 	qGisInterface->addToolBarIcon( mAction );
  49: 	qGisInterface->addPluginToMenu( tr("Add compass survey data layer"), mAction );
  50: }
  51: 
  52: void QgsCompassSurveyPlugin::unload()
  53: {
  54: 	qGisInterface->removeToolBarIcon( mAction );
  55: 	qGisInterface->removePluginMenu( tr("Add compass survey data layer"), mAction );
  56: 	delete mAction;
  57: }
  58: 
  59: void QgsCompassSurveyPlugin::run()
  60: {
  61: 	QgsCompassSurveyPluginGui *pdlg = 
  62: 		new QgsCompassSurveyPluginGui( qGisInterface, qGisInterface->mainWindow(), QgisGui::ModalDialogFlags );
  63: 
  64: 	pdlg->setAttribute( Qt::WA_DeleteOnClose );
  65: 	pdlg->show();
  66: }
  67: 
  68: 
  69: ///////////////////////////////////////////////////////////////////////////////
  70: 
  71: 
  72: QGISEXTERN QgisPlugin * classFactory( QgisInterface * theQgisInterfacePointer )
  73: {
  74: 	return new QgsCompassSurveyPlugin( theQgisInterfacePointer );
  75: }
  76: 
  77: QGISEXTERN QString name()
  78: {
  79: 	return QString( QObject::tr( "Add compass survey data layer" ) );
  80: }
  81: 
  82: QGISEXTERN QString description()
  83: {
  84: 	return description_;
  85: }
  86: 
  87: QGISEXTERN int type()
  88: {
  89: 	return QgisPlugin::UI;
  90: }
  91: 
  92: QGISEXTERN QString version()
  93: {
  94: 	return pluginVersion;
  95: }
  96: 
  97: QGISEXTERN void unload( QgisPlugin * theQgsCompassSurveyPluginPointer )
  98: {
  99: 	delete theQgsCompassSurveyPluginPointer;
 100: }

QgsCompassSurveyPluginGui.cpp

   1: #include "QgsCompassSurveyPluginGui.h"
   2: 
   3: QgsCompassSurveyPluginGui::QgsCompassSurveyPluginGui( QgisInterface * _qI, QWidget * parent, Qt::WFlags fl )
   4: {
   5: 	setupUi( this );
   6: }
   7: 
   8: QgsCompassSurveyPluginGui::~QgsCompassSurveyPluginGui(void)
   9: {
  10: }
  11: 
  12: void QgsCompassSurveyPluginGui::on_buttonBox_accepted()
  13: {
  14: }
  15: 
  16: void QgsCompassSurveyPluginGui::on_buttonBox_rejected()
  17: {
  18: 	reject();
  19: }
  20: 
  21: void QgsCompassSurveyPluginGui::OnBtnBrowse_clicked()
  22: {
  23: 	QString s = QFileDialog::getOpenFileName(
  24: 				this,
  25: 				tr( "Choose a text file to open" ),
  26: 				QDir().currentPath(),
  27: 				"Text files (*.txt *.csv);; All files (* *.*)" );
  28: 
  29: 	editFName->setText( s );
  30: }

QgsCompassSurveyPluginGui::OnBtnBrowse_clicked()関数内で、ファイルブラウザを起動する部分を実装しています。

プロジェクトの設定

QGIS用のプロジェクト設定を追加していきます。

プロジェクトの設定(デバッグ版)

メニューサブメニュー項目設定値
全般構成の種類ダイナミック ライブラリ (.dll)
文字セット設定なし
C++全般追加のインクルードディレクトリ{QGISのソースコードディレクトリ}srcgui
{QGISのソースコードディレクトリ}srcplugins
プリプロセッサプリプロセッサの定義WIN32;DEBUG;
CORE_EXPORT=__declspec(dllimport);
GUI_EXPORT=__declspec(dllimport);
QT_DLL;
QT_CORE_LIB;
_CRT_SECURE_NO_WARNINGS
リンカ入力追加の依存ファイルC:Qt2010.01qtlibQtCored4.lib
C:Qt2010.01qtlibqtmaind.lib
C:Qt2010.01qtlibQtGuid4.lib
{QGISのソースコードディレクトリ}buildsrccoreDebugqgis_core.lib
{QGISのソースコードディレクトリ}buildsrcguiDebugqgis_gui.lib

さらに、QtアプリケーションをVC2008で作成するには
にあるようにカスタムビルドステップとmocファイルの追加を行ってビルドを実行します。

ソリューションの状態

プロジェクトの状態

動作確認

できたDLLを{QGISインストールディレクトリ}/plugins/以下に置き、QGISを起動してプラグインマネージャを見てみましょう。
以下のように登録されていれば第一段階は成功です。

プラグインマネージャ

プラグインマネージャ

プラグインを有効にして、以下のようにツールバーに表示されれば第二段階は成功です。

ツールバーに追加される

ツールバーに追加される

本例ではアイコンを未だ作成していないのでこのように表示されます。
ボタンを押して、最初に作成したダイアログが表示されれば第三段階は成功です。

プラグインダイアログ

プラグインダイアログ

[browse]ボタンを押して、ファイルダイアログが起動し、選択したファイルがエディットボックスに表示されれば
一応全て成功です。

その4では、GUIプラグインからプロバイダプラグインを呼び出す部分を実装していきます。

QGIS プロバイダプラグイン その他のページ

アーカイブ