QGIS二次開發入坑指南
日前由於專案需求,學習了QGIS,並在QGIS上進行二次開發。在這裡記錄一下到目前為止的——入坑過程。
下載QGIS
下載QGIS可以從官網上直接下載。首先,我也是想著編譯一下原始碼,從原始碼學習。當我開始下載原始碼之後,並按照網上的一系列教程開始編譯時,到目前為止,我還沒有成功過。都是在VS中編譯時報各種錯誤。所以,本文不介紹原始碼編譯。當我哪天成功了,我再來補充。
下面介紹一下我所使用的環境:
- windows 10 (64位)
- VS2017 (或者VS2015)這兩個VS版本我都試過了
- qt5.9.2 (我使用的是這個地址) 其實在安裝QGIS的時候也會安裝對應的QT,但是由於我之前安裝過Qt,所以就直接使用之前的Qt了。 注意:使用自己提前下載的Qt會缺少幾個DLL(比如:Qt5WebkitWidgets.dll等),這幾個DLL在伴隨下載的Qt中
- QGIS 3.0.2-1(利用OSGeo4W下載得到),如下所示:
啟動VS,建立Qt工程
Qt開發環境配置:啟動VS2017,如果沒有安裝Qt VS tools的在”工具–>擴充套件和更新”中搜索並下載安裝。然後配置QtVSTools,新增Qt安裝的路徑。該部分內容可以自行百度。
當開發環境配置好了之後,建立Qt工程(Qt Gui Application)。在選擇匯入模組的時候勾選以下幾個(其實就是比預設的多選擇XML)
將編譯環境改成release x64(release是因為QGIS下載的都是release版本的,debug得自己編譯,x64是因為我的機器是64位的),然後編譯、執行,看看時候能否正常執行
配置專案屬性
在“C++” >>”常規” >> “附加包含目錄”中新增以下項(具體路徑需要做適當調整):
C:\path\to\OSGeo4W64\include
C:\path\to\OSGeo4W64\apps\qgis\include
在“連結器” >>”常規” >> “附加庫目錄”中新增以下項(具體路徑需要做適當調整):
C:\path\to\OSGeo4W64\apps\qgis\lib;
在“連結器” >>”輸入” >> “附加依賴項”中新增以下項:
qgis_app.lib
qgis_core.lib
qgis_gui.lib
修改專案檔案
1 修改main.cpp
如下所示
#include "ImageViewer.h"
#include <QtWidgets/QApplication>
#include <qgsapplication.h>
int main(int argc, char *argv[])
{
QgsApplication a(argc, argv, true);
QgsApplication::setPrefixPath("C:/path/to/OSGeo4W64/apps/qgis", true);
QgsApplication::initQgis(); //初始化QGIS應用
ImageViewer w; //建立一個窗體,類似於Qt
w.show();
return a.exec(); //進入QGIS應用的訊息迴圈
}
每一個QGIS的程式開始時都必須宣告建立QgsApplication,這個和Qt必須建立QApplication一樣,所以這裡就是將QApplication替換成QgsApplication。QgsApplication::setPrefixPath
是用來設定qgis的安裝路徑的,其實它主要作用是載入plugins。
2 修改ImageViewer.cpp
如下所示
#include "ImageViewer.h"
#include <qmenubar.h>
#include <qmessagebox.h>
#include <qfiledialog.h>
#include <qgsvectorlayer.h>
ImageViewer::ImageViewer(QWidget *parent)
: QMainWindow(parent)
{
this->resize(600, 400);
// create the menus and then add the actions to them.
fileMenu = this->menuBar()->addMenu("File");
openFileAction = new QAction("Open", this);
this->connect(openFileAction, SIGNAL(triggered(bool)), this, SLOT(on_openFileAction_triggered()));
fileMenu->addAction(openFileAction);
// initialize the map canvas
mapCanvas = new QgsMapCanvas();
this->setCentralWidget(mapCanvas);
mapCanvas->setCanvasColor(QColor(255, 255, 255));
mapCanvas->setVisible(true);
mapCanvas->enableAntiAliasing(true);
}
void ImageViewer::on_openFileAction_triggered() {
addVectorLayer();
}
void ImageViewer::addVectorLayer()
{
QString fileName = QFileDialog::getOpenFileName(this, tr("Open shape file"), "", "*.shp");
QStringList temp = fileName.split('/');
QString basename = temp.at(temp.size() - 1);
QgsVectorLayer* vecLayer = new QgsVectorLayer(fileName, basename, "ogr");
if (!vecLayer->isValid())
{
QMessageBox::critical(this, "error", QString("layer is invalid: \n") + fileName);
return;
}
mapCanvas->setExtent(vecLayer->extent());
layers.append(vecLayer);
mapCanvas->setLayers(layers);
mapCanvas->refresh();
}
該段程式碼主要的作用就是新增選單欄,在選單欄中新增“File”選單,然後在“File”選單中增加一個“Open” Action,並設定Open的響應函式。在響應函式中載入向量地圖檔案(.shp格式),並顯示在介面中。
3 修改ImageViewer.h
如下所示
#pragma once
#include <QtWidgets/QMainWindow>
#include <qmenu.h>
#include <qaction.h>
#include <qgsmapcanvas.h>
class ImageViewer : public QMainWindow
{
Q_OBJECT
public:
ImageViewer(QWidget *parent = Q_NULLPTR);
private:
// create the menus and then add the actions to them.
QMenu *fileMenu;
QAction *openFileAction;
//map canvas
QgsMapCanvas *mapCanvas;
QList<QgsMapLayer *> layers;
public slots:
void on_openFileAction_triggered();
//
public:
void addVectorLayer();
};
再次執行程式後會遇到缺少各種DLL的錯誤,這時候有兩種方法:
- 將
C:\path\to\OSGeo4W64\bin
和C:\path\to\OSGeo4W64\app\qgis\bin
新增到環境變數Path中 - 將
C:\path\to\OSGeo4W64\bin
和C:\path\to\OSGeo4W64\app\qgis\bin
中的DLL全部拷貝到生成的exe的目錄下。
這時再次執行程式,可能還是會缺少各種DLL,如果是以Qt5開頭的,在C:\path\to\OSGeo4W64\app\Qt5
中查詢;如果是其他的DLL,可以在你的系統中查詢,推薦使用everything。如果還是找不到需要的DLL,請自己百度下載或者請留言,看看我有沒有。
最後得到如下的結果: