4

I'm trying to develop a QT C++ application that uses QGIS API and I can't manage Qt Creator to compile the code. I've read several topicts at gis.stackexchange and from other sources. The information is mostly outdated and I havent't found a solution. What I need is an overall guideline about the compatibility of the following items that help me find the right combination:

  • Qt version: tried 4.8.6 and 5.9.
  • Qt compiler: tried MinGW, VS2008 Express (Qt 4.8.6) and VS Community 2017 (Qt 5.9)
  • QGIS version: tried 2.14 to 2.18.
  • QGIS compile: I only use the regular OSGeo4w installer and AFAIK QGIS is compiled with Qt4 and MSVC. I've tried to compile QGIS from source using MinGW with no success (again, versions compatibility issues).

  • Windows version: I'm using Windows 10 64bit.

  • OSGeo4W or OSGeo4W64.

Qt works Ok in every case with it's own libraries, but when I try to import QGIS libraries it gives an 'undefined reference' error when building, even though intellisense works fine as it recognizes QgsApplication as a member of qgsapplication.h.

The following is just a test I can't get working. My Pro file is:

QT       += core gui xml

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = QgisWindow
TEMPLATE = app

DEFINES += QT_DEPRECATED_WARNINGS

SOURCES += \
        main.cpp \
        mainwindow.cpp

HEADERS += \
        mainwindow.h

FORMS += \
        mainwindow.ui

# QGIS
INCLUDEPATH +=  "C:/OSGeo4W64/apps/qgis-rel-dev/include"
INCLUDEPATH +=  "C:/OSGeo4W64/include"

LIBS += -L"C:/OSGeo4W64/apps/qgis-rel-dev/lib" -lqgis_core -lqgis_gui

#DEFINES += GUI_EXPORT=__declspec(dllimport) CORE_EXPORT=__declspec(dllimport)
DEFINES+=CORE_EXPORT=
DEFINES+=GUI_EXPORT=
# QGIS

main.cpp is:

#include <QApplication>
#include <qgsapplication.h>


int main(int argc, char *argv[])
{
  QgsApplication app(argc, argv, true);
  QgsApplication::setPrefixPath("C:/OSGeo4W64/apps/qgis-dev", true);

  int retval = app.exec();
  QgsApplication::exitQgis();
  return retval;
}

Then it fails to build/compile whith this error:

main.cpp:20: error: undefined reference to `QgsApplication::QgsApplication(int&, char**, bool, QString const&, QString const&)'

I'm actually porting a PyQgis app I've made two years ago and as I'm fairly new to Qt Creator I'm stuck at he beginning.

4
  • This seems more CS-ish than GIS-ish; you might get a better response in StackOverflow.
    – Vince
    Jun 17, 2017 at 17:35
  • I agree. I also posted it there. Jun 17, 2017 at 21:23
  • Please don't add Solved: to the question title. We have an accept button for that. See also meta.stackexchange.com/questions/116101/…
    – AndreJ
    Aug 5, 2017 at 18:34
  • I am facing the same issue still and have followed your instruction number no of times but still getting the same error "C:\Users\Hp\Documents\mapcanvas6\main.cpp:21: error: undefined reference to `QgsMapCanvas::QgsMapCanvas(QWidget*, char const*)'". I am using QT 5.10.0 Apr 5, 2018 at 7:39

1 Answer 1

3

I found the right combination of the above mentioned items to make it possible for Qt to import Qgis libraries and build the app:

To launch Qt Creator I use this .bat:

Creator.bat:

ECHO Setting up QGIS DEV ENV

set PYTHONPATH=

set OSGEO4W_ROOT=C:\OSGeo4W
call "%OSGEO4W_ROOT%\bin\o4w_env.bat"

@set QMAKESPEC=win32-msvc2010

@set PATH=%OSGEO4W_ROOT%\bin;%OSGEO4W_ROOT%\apps\qgis-ltr-dev\bin;%PATH%

@set INCLUDE=%INCLUDE%;%OSGEO4W_ROOT%\include;%OSGEO4W_ROOT%\apps\qgis-ltr-dev\include

@set LIB=%LIB%;%OSGEO4W_ROOT%\lib;%OSGEO4W_ROOT%\apps\qgis-ltr-dev\lib

path %OSGEO4W_ROOT%\bin;%SYSTEMROOT%\System32;%SYSTEMROOT%;%SYSTEMROOT%\System32\wbem;C:\Program Files (x86)\Git\bin;C:\Tools\QtCreator\bin;%PATH%

set VS100COMNTOOLS=C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\Tools
call "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" x86

start "Qt Creator" /B C:\Qt\Qt5.9.0\Tools\QtCreator\bin\qtcreator.exe %*

The PRO file:

QT       += core gui xml

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = 1_hello_world_qgis_style
TEMPLATE = app

DEFINES += QT_DEPRECATED_WARNINGS

SOURCES += main.cpp

## QGIS
INCLUDEPATH +=  "C:/OSGeo4W/include"
INCLUDEPATH +=  "C:/OSGeo4W/apps/qgis-ltr-dev/include"

LIBS += -L"C:/OSGeo4W/apps/qgis-ltr-dev/lib" -lqgis_core -lqgis_gui

DEFINES+=CORE_EXPORT=
DEFINES+=GUI_EXPORT=
## QGIS

main.cpp file (adapted from Tim Sutton's examples)

// Qt Includes
#include <QApplication>

// QGIS Includes
#include <qgsapplication.h>
#include <qgsproviderregistry.h>
#include <qgssinglesymbolrendererv2.h>
#include <qgsmaplayerregistry.h>
#include <qgsvectorlayer.h>
#include <qgsmapcanvas.h>

int main(int argc, char ** argv)
{

    // Start the Application
    QgsApplication app(argc, argv, true);

    app.setPrefixPath("D:/GIS");

    QString myPluginsDir        = "<path to Qgis plugins dir>";
    QString myLayerPath1         = "<path to shapefile 1>";
    QString myLayerBaseName1     = "Layer1";
    QString myLayerPath2         = "<path to shapefile 2>";
    QString myLayerBaseName2     = "Layer2";
    QString myProviderName      = "ogr";

    // Instantiate Provider Registry
    QgsProviderRegistry::instance(myPluginsDir);
    // create maplayer instances
    QgsVectorLayer * mypLayer1 = new QgsVectorLayer(myLayerPath1, myLayerBaseName1, myProviderName);
    QgsVectorLayer * mypLayer2 = new QgsVectorLayer(myLayerPath2, myLayerBaseName2, myProviderName);
    QgsSingleSymbolRendererV2 *mypRenderer1 = new QgsSingleSymbolRendererV2(QgsSymbolV2::defaultSymbol(mypLayer1->geometryType()));
    QgsSingleSymbolRendererV2 *mypRenderer2 = new QgsSingleSymbolRendererV2(QgsSymbolV2::defaultSymbol(mypLayer2->geometryType()));
    QList <QgsMapCanvasLayer> myLayerSet;
    mypLayer1->setRendererV2(mypRenderer1);
    mypLayer2->setRendererV2(mypRenderer2);

    // Add Vector Layers to the Layer Registry
    QgsMapLayerRegistry::instance()->addMapLayer(mypLayer1, true);
    QgsMapLayerRegistry::instance()->addMapLayer(mypLayer2, true);
    // Add Layers to the Layer Set
    myLayerSet.append(QgsMapCanvasLayer(mypLayer1, true));
    myLayerSet.append(QgsMapCanvasLayer(mypLayer2, true));

    // Create the Map Canvas
    QgsMapCanvas * mypMapCanvas = new QgsMapCanvas(0, 0);
    mypMapCanvas->setExtent(QgsRectangle(-63.50, -28.10, -58.33, -24.00));  // Chaco
    mypMapCanvas->setWheelAction(QgsMapCanvas::WheelAction(2) , 1.2);
    mypMapCanvas->enableAntiAliasing(true);
    mypMapCanvas->setCanvasColor(QColor(255, 255, 255));
    mypMapCanvas->freeze(false);
    // Set the Map Canvas Layer Set
    mypMapCanvas->setLayerSet(myLayerSet);
    mypMapCanvas->setVisible(true);
    mypMapCanvas->setWindowTitle("GIS DSH");
    mypMapCanvas->refresh();

    // Start the Application Event Loop
    int retval = app.exec();

    app.exitQgis();

    return retval;
}

Paths are hardcoded (bad programming practice) but is just for this test.

Qt Build & Run configuration

Kits

Qt versions

Compilers

Debuggers

CMake

And now it runs OK:

GIS DSH

A simple shapefile viewer, but it's just the beginning!!!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.