摘要: 一、Qgis工作原理 QGIS需要加载数据,并能够管理相关数据,然后显示出来。 QGIS有几个全局单例,用于维护整个工程中全局配置。 QGIS管理数据使用注册表Registry类,每个管理类都有相应的注册表类。 注意: 错误:global\qglobal.cp...
一、Qgis工作原理
QGIS需要加载数据,并能够管理相关数据,然后显示出来。
QGIS有几个全局单例,用于维护整个工程中全局配置。
QGIS管理数据使用注册表Registry类,每个管理类都有相应的注册表类。
注意:
错误:global\qglobal.cpp L2262
QWidget must construct a QApplication beforeQPaintDevice
是由于使用QT的release库dll,但是在debug模式下,使用了debug的dll。修改方法为将qt 的release库dll添加到工程中。
1.全局工程单例
(1)QgsApplication::instance()
QApplication的扩展类,在工程中代替QApplication。
本类的用途是配置工程的全局路径和变量。所有配置信息应该只出现在本类中。大部分成员函数为静态。
setPluginPath():设置插件的目录。在Qgis的install工程编译后,会有一个plugin文件夹。
initQgis():生成QgsProviderRegistry、QgsMapLayerRegistry的单例,用于管理驱动和图层。
(2)QgsProject::instance()
读写工程文件状态。
当前qgis每个应用只有一个工程,但未来不确定是否可以使用多个工程。
2.全局数据管理注册表单例类
(1)QgsProviderRegistry
也是一个全局单例类,用于管理全局驱动。
在Qgis::initQgis()中生成单例。
(2)QgsMapLayerRegistry
也是一个全局单例类,用于管理全局图层数据(不管理显示)。
在Qgis::initQgis()中生成单例。
3.图层管理类QgsLayerTree
QgsLayerTreeNode:代表单一图层。
QgsLayerTreeGroup:node的容器。
QgsLayerTreeLayer:node的子类,代表QgsMapLayerRegistry中一个图层。
4.显示数据的主窗口QgsMapCanvas
(1)QgsMapCanvas
所有数据在此控件中显示。交互功能也在此控件中控制。
freeze():用于阻止事件,在图层加载、删除时应该先冻结,完成后解冻。
refresh():重绘。
(2)QgsLayerTreeMapCanvasBridge
连接QgsMapCanvas和QgsLayerTreeGroup,管理所有图层的显示。
图层的可见性、图层的加入、删除等显示图层显示的,都在这里管理。
QgsMapCanvas必须要有一个此类对象来管理图层的显示状态。
二、QGIS构建空白工程(vs2008)
1.准备
(1)构建Qt Application工程:选择core,gui,xml模块。
(2)添加库头引用:OSGEO4W/include,QGIS/include
(3)添加宏指令:
CORE_EXPORT=__declspec(dllimport)
GUI_EXPORT=__declspec(dllimport)
PYTHON_EXPORT=__declspec(dllimport)
ANALYSIS_EXPORT=__declspec(dllimport)
APP_EXPORT=__declspec(dllimport)
CUSTOMWIDGETS_EXPORT=__declspec(dllimport)
(4)添加库lib目录和lib文件:
OSGEO4W/lib,QGIS/lib
这里要特别注意,在vs下,会默认添加debug版的qt lib文件(有d后缀),如果发现,一定要替换为release(无d后缀)版的。
qgis_core.lib
qgis_gui.lib
qgis_analysis.lib
qtcore.lib
qtgui.lib
qtxml.lib
qtmain.lib
(5)拷贝相应的dll文件:
主要是OSGEO4W/bin和qgis bin下的文件。
如果要发布程序,必须把所有的dll入在exe目录下。如果只是调试可以把dll的目录(osgeo4w\bin,c:\program files (x86)\qgis2.4.0\bin)放在path环境变量下,省去了每次都得拷贝(设置完path后,重启vs才能生效)。
2.逻辑
(1)将main.cpp下的main函数中QApplication对象,修改为QgsApplication对象,修改相应的构造函数。
(2)将myclass.cpp下的构造函数,修改为设置QgsApplication,初始化QgsMapCanvas。
////main.cpp #include "myclass.h" #include#include int main(int argc,char *argv[]) { QgsApplicationa(argc, argv,true,QString()); MyClass*pQgis = new MyClass; pQgis->show(); int iRet = a.exec(); delete pQgis; return iRet; } //////myclass.cpp #include "myclass.h" #include #include #include MyClass::MyClass(QWidget *parent,Qt::WFlags flags) :QMainWindow(parent, flags) { ui.setupUi(this); //qgsapp QgsApplication::setPluginPath("C:/Program Files (x86)/qgis2.4.0/plugins"); QgsApplication::initQgis(); //mapcanvas QWidget*pCenter = ui.centralWidget; QGridLayout*pLayout = new QGridLayout; pCenter->setLayout(pLayout); pLayout->setContentsMargins(0,0,0,0); QgsMapCanvas*pMapCanvas = new QgsMapCanvas(pCenter,"myMapCanvas"); pMapCanvas->setCanvasColor(QColor(0,255,0)); pLayout->addWidget(pMapCanvas); pMapCanvas->setFocus(); pMapCanvas->show(); } MyClass::~MyClass() { }
(3)编译,运行,出现一个绿框,成功
三、QGIS构建空白工程(qt4.7.1+qtcreator3.1.2)
1.准备
(1)创建QWidgetApplication
(2)修改Pro文件
因为Qt在Debug下使用d.dll,而Qgis使用.dll编译,会出现无法编译的问题,所以要修改为使用release版的qt库,如下:
//.pro文件 #------------------------------------------------- # #ProjectcreatedbyQtCreator2014-08-12T09:27:02 # #------------------------------------------------- #QT +=coreguixml QT-=coregui #greaterThan(QT_MAJOR_VERSION,4):QT+=widgets TARGET=blankpro TEMPLATE=app SOURCES+=main.cpp\ mainwindow.cpp HEADERS +=mainwindow.h FORMS +=mainwindow.ui INCLUDEPATH+=C:/OSGeo4W/include$$quote(C:/ProgramFiles(x86)/qgis2.4.0/include)\ C:/OSGeo4W/include/qt4/qtcoreC:/OSGeo4W/include/qt4/qtgui\ C:/OSGeo4W/include/qt4/qtxml LIBS+=-LC:/OSGeo4W/lib-L$$quote(C:/ProgramFiles(x86)/qgis2.4.0/lib)\ qgis_core.libqgis_gui.libqgis_analysis.lib\ qtcore4.libqtgui4.libqtxml4.libqtmain.lib DEFINES+=CORE_EXPORT=__declspec(dllimport)GUI_EXPORT=__declspec(dllimport)\ PYTHON_EXPORT=__declspec(dllimport)ANALYSIS_EXPORT=__declspec(dllimport)\ APP_EXPORT=__declspec(dllimport)CUSTOMWIDGETS_EXPORT=__declspec(dllimport)
(3)拷贝相应的dll文件:
主要是OSGEO4W/bin 和qt/bin下的文件。可以双击exe文件,看看需要哪些,也可以直接使用dependswalk.exe 检测dll依赖文件。
2.逻辑
与vs基本相同。
(1)修改main.cpp,以QgsApplication代替QApplication。
(2)修改mainwindow.cpp,添加相关逻辑代码。
///main.cpp #include"mainwindow.h" #include#include intmain(intargc,char*argv[]) { QgsApplicationapp(argc,argv,TRUE,QString()); MainWindow*pMainWindow=newMainWindow(0); pMainWindow->show(); app.setActiveWindow(pMainWindow); intiRet=app.exec(); deletepMainWindow; returniRet; } /////mainwindow.cpp #include"mainwindow.h" #include"ui_mainwindow.h" #include #include #include MainWindow::MainWindow(QWidget*parent): QMainWindow(parent), ui(newUi::MainWindow) { ui->setupUi(this); //qgsapp QgsApplication::setPluginPath("C:/ProgramFiles(x86)/qgis2.4.0/plugins"); QgsApplication::initQgis(); //mapcanvas QWidget*pCenter=ui->centralWidget; QGridLayout*pLayout=newQGridLayout; pCenter->setLayout(pLayout); pLayout->setContentsMargins(0,0,0,0); QgsMapCanvas*pMapCanvas=newQgsMapCanvas(pCenter,"myMapCanvas"); pMapCanvas->setCanvasColor(QColor(0,255,0)); pLayout->addWidget(pMapCanvas); pMapCanvas->setFocus(); pMapCanvas->show(); } MainWindow::~MainWindow() { deleteui; }