QGIS二次開發入坑指南

日前由於項目需求,學習了QGIS,並在QGIS上進行二次開發。在這裏記錄一下到目前爲止的——入坑過程。

下載QGIS

下載QGIS可以從官網上直接下載。首先,我也是想着編譯一下源碼,從源碼學習。當我開始下載源碼之後,並按照網上的一系列教程開始編譯時,到目前爲止,我還沒有成功過。都是在VS中編譯時報各種錯誤。所以,本文不介紹源碼編譯。當我哪天成功了,我再來補充。

下面介紹一下我所使用的環境:

  1. windows 10 (64位)
  2. VS2017 (或者VS2015)這兩個VS版本我都試過了
  3. qt5.9.2 (我使用的是這個地址) 其實在安裝QGIS的時候也會安裝對應的QT,但是由於我之前安裝過Qt,所以就直接使用之前的Qt了。 注意:使用自己提前下載的Qt會缺少幾個DLL(比如:Qt5WebkitWidgets.dll等),這幾個DLL在伴隨下載的Qt中
  4. 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的錯誤,這時候有兩種方法:

  1. C:\path\to\OSGeo4W64\binC:\path\to\OSGeo4W64\app\qgis\bin添加到環境變量Path中
  2. C:\path\to\OSGeo4W64\binC:\path\to\OSGeo4W64\app\qgis\bin中的DLL全部拷貝到生成的exe的目錄下。

這時再次運行程序,可能還是會缺少各種DLL,如果是以Qt5開頭的,在C:\path\to\OSGeo4W64\app\Qt5中查找;如果是其他的DLL,可以在你的系統中查找,推薦使用everything。如果還是找不到需要的DLL,請自己百度下載或者請留言,看看我有沒有。

最後得到如下的結果:
這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章