QGIS开发笔记(三):Windows安装版二次开发环境搭建(下):将QGis融入QtDemo,添加QGis并加载tif遥感图的Demo

qgis,windows,qtdemo,tif,demo · 浏览次数 : 0

小编点评

## QGIS二次开发环境搭建指南 **一、安装 dependencies** * 下载和解压缩 qgis-3.34.7.zip 文件 * 将 `qgis-3.34.7.h` 和 `qgis-3.34.7.cpp` 文件添加到工程中 * 设置 QGIS 编码为 UTF-8 **二、新建模块并引入基本的qgis库** * 创建一个新的 C++17 模块文件 `TestWidget.h` * 引入 qgis 库头文件 `qgsapplication.h`、`qgsmapcanvas.h`、`qgsmaptoolpan.h` * 定义一个新的 C++17 模块文件 `TestWidget.cpp` **三、编写模块代码** ```cpp #include "TestWidget.h" #include "ui_TestWidget.h" #include #include #include #include TestWidget::TestWidget(QWidget *parent = 0) : QWidget(parent), ui(new Ui::TestWidget){...} // 其他成员函数... ``` **四、编写 UI 文件** ```ui #include "TestWidget.h" class Ui::TestWidget : public QWidget{ Q_OBJECT public: explicit TestWidget(QWidget *parent = 0); ~TestWidget(); private: Ui::TestWidget *ui; }; ``` **五、构建应用程序** * 创建一个 `QMainWindow` * 设置 `TestWidget` 为 `MainWindow` 的子窗口 * 设置 `TestWidget` 的大小和位置 * 设置 `TestWidget` 的编码为 UTF-8 **六、运行应用程序** ```cpp int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); QMainWindow window; window.setWindowTitle("QGisDemo"); window.setMinimumSize(640, 480); window.setMaximumSize(640, 480); TestWidget *widget = new TestWidget; window.setCentralWidget(widget); window.show(); return app.exec(); } ``` **七、运行应用程序** 运行程序,应该可以看到 QGIS 的演示画面。

正文

前言

  使用QGis的目的是进行二次开发,或者说是融入我们的应用(无人车、无人船、无人机),本片描述搭建QGis二次基础开发环境,由于实在是太长了,进行了分篇:

  • 上半部分:主要是安装好后,使用QtCreator可以使用QGIs的apps下的Qt使用对应的编译器编译不带qgis的空工程。
  • 下半部分:在上半部分基础上添加qgis的依赖,并实现一个qgis的完全独立模模块化的应用,让没有安装qgis库的使用工程模板可以开始二次开发编译。
 

Demo

  空demo
  在这里插入图片描述

  运行qgis的demo
  请添加图片描述

 

给Demo引入QGIS库

步骤一:添加qgis代码

  新建QWidget的子类TestWidget,使用常规initControl添加布局嵌套窗口方式,来实现在QApplication消息循环里面的窗口类里面添加单独的qgis窗口。
  在这里插入图片描述

void TestWidget::testEnv(QString filePath)
{
    QHBoxLayout *pHBoxLayout = dynamic_cast<QHBoxLayout *>(this->layout());
    if(!pHBoxLayout)
    {
        pHBoxLayout = new QHBoxLayout(this);
        LOG;
    }


    QgsMapCanvas *pMapCanvas = new QgsMapCanvas();

    // 本地影像路径
    QgsRasterLayer *pLayer = new QgsRasterLayer(filePath);
    pMapCanvas->setLayers({pLayer});
    pMapCanvas->setExtent(pLayer->extent());
    pMapCanvas->refresh();

    QgsMapToolPan *pMapToolPan = new QgsMapToolPan(pMapCanvas);
    pMapCanvas->setMapTool(pMapToolPan);

    pHBoxLayout->addWidget(pMapCanvas, 1);

    pMapCanvas->show();

    setLayout(pHBoxLayout);
}

步骤二:新建模块,并引入基本的qgis库

  在这里插入图片描述

  在这里插入图片描述

  然后开始编译。

步骤三:新增支持c++17配置

  编译出错如下:
  在这里插入图片描述

   支持c++17
  在这里插入图片描述

步骤四:支持数学宏定义

  在这里插入图片描述

  未定义M_Pi添加
  在这里插入图片描述

  最终,添加了win32下自动copy的脚本
  在这里插入图片描述

步骤五:运行奔溃寻找依赖库

  编译通过,但是运行崩溃,这里不好直接把bin全部copy过来,所以用打包的方式确定少了那些库,补充一个打包环境:
  在这里插入图片描述

  在这里插入图片描述

  这个打包之后,像Qt5Xml.dll也没有包含进去,但是实际apps/qt5/bin下是有的,这个只能说单独弄sdk不是 很完善,目前靠个人完善。
  完善之后发现:
  在这里插入图片描述

  基本就是OSGeo4W/bin下大部分库和OSGeo4W/apps/Qt5/bin下大部分库了:
  在这里插入图片描述

  没有添加Qgis代码,添加之后还少qgis_gui.dll,apps下qgis-lts中bin的dll(就qgis的直接库),所以后来干脆直接三个bin目录下下的dll都拷贝了,需要精简再反向减少即可。
  在这里插入图片描述

 

关键代码

qgis3.34.7env.pri

INCLUDEPATH += $$PWD
DEPENDPATH += $$PWD

# 需要QDomDocument
QT += xml

# 需要支持c++17
CONFIG += c++17

# 未定义M_PI、M_PI_2添加
DEFINES += _USE_MATH_DEFINES

win32{
    # copy ffmpeg
    src_file = $$PWD/qgis-ltr/bin/*
    dst_file = $$OUT_PWD
#    target_file = $$DESTDIR
    src_file ~= s,/,\\,g
    dst_file ~= s,/,\\,g
#    target_file ~= s,/,\\,g
    system(xcopy $$src_file $$dst_file /y /s/q/e)
#    system(xcopy $$src_file $$target_file /y /s/q/e)
}



INCLUDEPATH += $$PWD/qgis-ltr/include
LIBS += -L$$PWD/qgis-ltr/lib \
        -lqgis_3d \
        -lqgis_analysis \
        -lqgis_app \
        -lqgis_core \
        -lqgis_gui \
        -lqgis_native \
        -lqgis_server



HEADERS += \
    $$PWD/qgis3.34.7.h

qgis3.34.7.h

#ifndef QGIS3_34_7_H
#define QGIS3_34_7_H

#include <qgsapplication.h>
#include <qgsmapcanvas.h>
#include <qgsmaptoolpan.h>
#include <qgsrasterlayer.h>
#include <QtMath>

#endif // QGIS3_34_7_H
TestWidget.cpp
#include "TestWidget.h"
#include "ui_TestWidget.h"

#include <QHBoxLayout>
#include <QBoxLayout>
#include <QPushButton>

#include "qgis3.34.7.h"

// QtCreator在msvc下设置编码也或有一些乱码,直接一刀切,避免繁琐的设置
#define MSVC
#ifdef MSVC
#define QSTRING(s)  QString::fromLocal8Bit(s)
#else
#define QSTRING(s)  QString(s)
#endif

#include <QDebug>
#include <QDateTime>
//#define LOG qDebug()<<__FILE__<<__LINE__
//#define LOG qDebug()<<__FILE__<<__LINE__<<__FUNCTION__
//#define LOG qDebug()<<__FILE__<<__LINE__<<QThread()::currentThread()
//#define LOG qDebug()<<__FILE__<<__LINE__<<QDateTime::currentDateTime().toString("yyyy-MM-dd")
#define LOG qDebug()<<__FILE__<<__LINE__<<QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz")

TestWidget.h

#ifndef TESTWIDGET_H
#define TESTWIDGET_H

#include <QWidget>

namespace Ui {
class TestWidget;
}

class TestWidget : public QWidget
{
    Q_OBJECT

public:
    explicit TestWidget(QWidget *parent = 0);
    ~TestWidget();

public:
    void testEnv(QString filePath);

protected:
    void initControl();

private:
    Ui::TestWidget *ui;
};

#endif // TESTWIDGET_H

TestWidget.cpp

TestWidget::TestWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::TestWidget)
{
    ui->setupUi(this);

    QString version = "v1.0.0";
    setWindowTitle(QSTRING("QGisDemo %1(作者:长沙创微智科信息技术有限公司 QQ:21497936 WX:15173255813 www.chuangweizhike.com)").arg(version));

    initControl();

}

TestWidget::~TestWidget()
{
    delete ui;
}

void TestWidget::initControl()
{
}

void TestWidget::testEnv(QString filePath)
{
    QHBoxLayout *pHBoxLayout = dynamic_cast<QHBoxLayout *>(this->layout());
    if(!pHBoxLayout)
    {
        pHBoxLayout = new QHBoxLayout(this);
        LOG;
    }


    QgsMapCanvas *pMapCanvas = new QgsMapCanvas();

    // 本地影像路径
    QgsRasterLayer *pLayer = new QgsRasterLayer(filePath);
    pMapCanvas->setLayers({pLayer});
    pMapCanvas->setExtent(pLayer->extent());
    pMapCanvas->refresh();

    QgsMapToolPan *pMapToolPan = new QgsMapToolPan(pMapCanvas);
    pMapCanvas->setMapTool(pMapToolPan);

    pHBoxLayout->addWidget(pMapCanvas, 1);

    pMapCanvas->show();

    setLayout(pHBoxLayout);
}
 

模块化

  在这里插入图片描述

 

工程模板v1.0.0

  在这里插入图片描述

 

入坑

入坑一:无法加载tif图像

问题

  在这里插入图片描述

过程

  开始以为是无法直接在QWidget加载,可以在QMainWindow里面加载,后来经过判断是因为变量的问题,在main函数里面是因为是全局的,所以exec()之后是存在的,而放到Qt窗口构造里面,则是new出来的就可以,简单来说就是保持对象存在。

解决

  局部改成new即可:
  在这里插入图片描述

与QGIS开发笔记(三):Windows安装版二次开发环境搭建(下):将QGis融入QtDemo,添加QGis并加载tif遥感图的Demo相似的内容: