Qt+ArcGIS Engine 10.1 开发(一)
Qt作为一个跨平台C++图形用户界面应用程序开发框架,相当于微软的MFC(只能运行在Windows平台上),Qt命运多舛,几经易主,现在属于芬兰IT服务公司Digia。
Qt环境安装
Qt的最新版本是Qt5.0,该版本是在12月中旬发布的,在这里我用的是Qt4.8。1版本,也不建议大家着急着用最新版本,关于软件的下载地址可以在下面找到。
http://download.qt.nokia.com/qt/source/
http://qt-project.org/downloads#qt-other
安装过程很单,只需要点击下一部即可。
因为我采用的是VS2010作为Qt的集成开发环境,整个开发环境需要下载两个软件
http://download.qt.nokia.com/qt/source/qt-win-opensource-4.8.1-vs2010.exe
http://releases.qt-project.org/vsaddin/qt-vs-addin-1.1.11-opensource.exe
说明:
如果有人不愿意这么做,还可以使用QtCreator以及qt-win-opensource-4.8.1-mingw.exe的组合,因为新版本的QtCreator已经不包含mingw,所以要单独下载。
Qt的第一个程序
安装完后,需要配置几个环境变量,QMAKESPE(根据自己的情况配置,因为我用的是VS2010,所有配置win32-msvc2010),如下图:
QTDIR(Qt的安装目录),如下图:
在Path中添加Qt的bin目录如下图:
打开VS2010,新建工程可以找到Qt4 的模板:
完成之后,在VS中运行,出现下面的界面,因为我们什么都没做,在弹出的界面上什么都没有,不过没关系,只要能出现,就说明我们的Qt已经可以使用了,如下图:
ArcGIS Engine的环境
安装ArcGIS ArcObjects for Cross Platform C++ 的SDK,这个没有什么好说的。
ArcGIS Engine+Qt(控制台开发)
安装了SDK之后,我们就需要将ArcGIS Engine的类库等引入到开发环境中,在Qt中引入ArcGIS Engine的类库等信息.在新建立的Qt控制台程序工程右键,找到C/C++,然后找到常规,在右侧的附加包含目录中输入下面三个目录的地址(因为我的有x(86),所以出现了下面的特殊符号):
说明:在MFC中我们除了引入三个目录地址,还配置了预处理器定义"ESRI_WINDOW",在这里我并没有配置。
配置好这个之后,在主程序文件中输入代码(这个代码我在这里就不做解释,到时候可以看这个文档的姊妹篇- 《VC2010+ArcGIS Engine10.1开发》
,最后效果如下:
#include <QtCore/QCoreApplication>
#include "ArcSDK.h"
#include "qtextstream.h"
int main(int argc, char *argv[])
{
::CoInitialize(NULL);
#pragma region 绑定许可
IArcGISVersionPtr ipVer(__uuidof(VersionManager));
VARIANT_BOOL succeeded;
if (FAILED(ipVer->LoadVersion(esriArcGISEngine , L"10.1",&succeeded)))
return 0;
#pragma endregion
//
#pragma region 初始化许可
IAoInitializePtr ipInit(CLSID_AoInitialize);
esriLicenseStatus status;
ipInit->Initialize(esriLicenseProductCodeEngine, &status);
if (status != esriLicenseCheckedOut)
{
AoExit(0);
return 0;
}
#pragma endregion
QCoreApplication a(argc, argv);
#pragma region 打开工作空间
IWorkspaceFactoryPtr ipWorkspaceFactory(CLSID_ShapefileWorkspaceFactory);
IWorkspacePtr pWs;
BSTR bstr_str;
QString q_str="D:\\guest\\chinasimplify";
bstr_str = SysAllocString(q_str.utf16());
HRESULT hr=ipWorkspaceFactory->OpenFromFile(bstr_str,0,&pWs);
SysFreeString(bstr_str);
QString q_str1="china_simply.shp";
BSTR bStringWS=SysAllocString(q_str1.utf16());
if (FAILED(hr))
{
return 0;
}
#pragma endregion
#pragma region QI 这里和NET下不一样
IFeatureWorkspacePtr ipRastWork (pWs);
#pragma endregion
#pragma region 打开要素类并获取个数
IFeatureClassPtr pFtClass;
hr=ipRastWork->OpenFeatureClass(bStringWS,&pFtClass);
SysFreeString(bStringWS);
if (FAILED(hr))
{
return 0;
}
long pCount=0;
pFtClass->FeatureCount(NULL,&pCount);
#pragma endregion
QString s = QString::number(pCount, 10);
QTextStream cout(stdout);
cout<<s<< endl;
QString str;
QTextStream in(stdin);
in >> str;
return a.exec();
}
运行后可以看到下面的效果
ArcGIS Engine+Qt(GUI开发)
在MFC中我们介绍了两种开发GUI的方法,一种是通过生成相应的Activex控件MFC类,另一种是通过插入Activex控件的方法,在Qt里面做GUI的AE开发,也有两种不同的做法,而这两种做法需要引入的头文件也有差异,除了头文件的差异,我们需要配置额外的信息,在这里我们分别对两种方法介绍。
ArcGIS Engine+Qt(GUI开发,使用Esri提供的控件类)
额外的配置
对于这种方法,需要配置很多信息,在工程项目的连接器的常规中找到SDK的lib目录(在MFC的开发中,我们应该没有这个步骤),如下图:
在附加依赖项中输入qt4ctl.lib和aoctl.lib文件如下图:
此外还要在环境变量中配置Path(不一定要在Path中配置,只要在运行的时候能找到相应的文件即可),要不然在运行的时候会报下面的错误,如下图:
这是因为Qt的AE在运行的时候用到了Engine安装目录下的bin下的三个文件:Qt4ctl.dll, aoctl.dll, ctlbase.dll,只要将Engine的bin目录配置到Path中就可以了,如下图:
Esri提供的控件类
当这些信息配置好了,我们就可以开发出GUI程序了,在Qt中我们认为一个可视化的组件是一个QWidget,这个QWidget类似MFC中的窗体,一旦有了这些QWidget,就可以用父组件的addWdiget方法加入,Esri提供了继承这些控件QWidget的类,我们可以在qtaxtcl.h头文件中找到,如下:
class ESRI_EXT_CLASS QAxCtl
: public QWidget
{
public:
QAxCtl(const char *progID = NULL, QWidget *parent = NULL, const char *name = NULL);
QAxCtl(const ControlDataPtr progID, QWidget *parent = NULL, const char *name = NULL);
~QAxCtl();
HRESULT getInterface(IUnknown **ppUnk);
HRESULT setCursor(HCURSOR cur);
protected:
bool eventFilter(QObject *qo, QEvent *qe);
#if defined(ESRI_UNIX)
bool x11Event(XEvent *event);
#endif /* ESRI_UNIX */
private:
char *m_sProgID;
AxContainerPtr m_pAxCont;
void initialize(const char *progID);
};
代码编写
我们将这种GUI开发的先决条件都准备好了,下来就开始一个简单的GUI,这个例子我只将TOC,Map和Toolbar三个控件添加上去,并在Toolbar上添加了几个命令和工具,完整的代码如下(功能也比较简单,界面也不好看,只是当做一个例子,大家就将就看):
#include <stdio.h>
#include <qapplication.h>
#include <qpushbutton.h>
#include <qboxlayout.h>
#include <qsplitter.h>
#include <ArcSDK.h>
#include <AxCtl/qt4axctl.h>
#include <Ao/AoControls.h>
void add_toolbar_items(IToolbarControl* pToolbar);
int main(int argc, char **argv)
{
::CoInitialize(NULL);
#pragma region 绑定许可
IArcGISVersionPtr ipVer(__uuidof(VersionManager));
VARIANT_BOOL succeeded;
if (FAILED(ipVer->LoadVersion(esriArcGISEngine , L"10.1",&succeeded)))
return 0;
#pragma endregion
IAoInitializePtr ipInit(CLSID_AoInitialize);
esriLicenseStatus status;
ipInit->Initialize(esriLicenseProductCodeEngine, &status);
if (status != esriLicenseCheckedOut)
{
printf("Invalid Licensing.\n");
AoExit(0);
}
QApplication qapp(argc, argv);
QWidget window;
window.resize(500,400);
QVBoxLayout vbox(NULL);
QAxCtl tlb(AoPROGID_ToolbarControl);
tlb.setMinimumHeight(30);
tlb.setMaximumHeight(30);
QSplitter split;
QAxCtl toc(AoPROGID_TOCControl);
QAxCtl map(AoPROGID_MapControl);
window.setLayout(&vbox);
vbox.addWidget(&tlb);
split.addWidget(&toc);
split.addWidget(&map);
vbox.addWidget(&split);
IToolbarControlPtr ipToolbar;
IMapControl3Ptr ipMap;
ITOCControlPtr ipToc;
HRESULT hr;
hr = tlb.getInterface((IUnknown **)&ipToolbar);
hr = toc.getInterface((IUnknown **)&ipToc);
hr = map.getInterface((IUnknown **)&ipMap);
if (ipToolbar != 0)
ipToolbar->SetBuddyControl(ipMap);
if (ipToc != 0)
ipToc->SetBuddyControl(ipMap);
add_toolbar_items(ipToolbar);
window.show();
qapp.exec();
ipInit->Shutdown();
::CoUninitialize();
AoExit(0);
return 0;
}
void add_toolbar_items(IToolbarControl* pToolbar)
{
CComVariant varTool;
long itemindex;
if (!pToolbar)
return;
varTool = L"esriControlCommands.ControlsOpenDocCommand";
pToolbar->AddItem(varTool, 0, -1, VARIANT_FALSE, 0,
esriCommandStyleIconOnly, &itemindex);
varTool = L"esriControlCommands.ControlsAddDataCommand";
pToolbar->AddItem(varTool, 0, -1, VARIANT_FALSE, 0,
esriCommandStyleIconOnly, &itemindex);
varTool = L"esriControlCommands.ControlsMapZoomInTool";
pToolbar->AddItem(varTool, 0, -1, VARIANT_TRUE, 0,
esriCommandStyleIconOnly, &itemindex);
varTool = L"esriControlCommands.ControlsMapZoomOutTool";
pToolbar->AddItem(varTool, 0, -1, VARIANT_FALSE, 0,
esriCommandStyleIconOnly, &itemindex);
varTool = L"esriControlCommands.ControlsMapZoomInFixedCommand";
pToolbar->AddItem(varTool, 0, -1, VARIANT_FALSE, 0,
esriCommandStyleIconOnly, &itemindex);
varTool = L"esriControlCommands.ControlsMapZoomOutFixedCommand";
pToolbar->AddItem(varTool, 0, -1, VARIANT_FALSE, 0,
esriCommandStyleIconOnly, &itemindex);
varTool = L"esriControlCommands.ControlsMapPanTool";
pToolbar->AddItem(varTool, 0, -1, VARIANT_FALSE, 0,
esriCommandStyleIconOnly, &itemindex);
varTool = L"esriControlCommands.ControlsMapFullExtentCommand";
pToolbar->AddItem(varTool, 0, -1, VARIANT_FALSE, 0,
esriCommandStyleIconOnly, &itemindex);
varTool = L"esriControlCommands.ControlsMapZoomToLastExtentBackCommand";
pToolbar->AddItem(varTool, 0, -1, VARIANT_FALSE, 0,
esriCommandStyleIconOnly, &itemindex);
varTool = L"esriControlCommands.ControlsMapZoomToLastExtentForwardCommand";
pToolbar->AddItem(varTool, 0, -1, VARIANT_FALSE, 0,
esriCommandStyleIconOnly, &itemindex);
varTool = L"esriControlCommands.ControlsSelectFeaturesTool";
pToolbar->AddItem(varTool, 0, -1, VARIANT_FALSE, 0,
esriCommandStyleIconOnly, &itemindex);
varTool = L"esriControlCommands.ControlsSelectTool";
pToolbar->AddItem(varTool, 0, -1, VARIANT_FALSE, 0,
esriCommandStyleIconOnly, &itemindex);
}
运行效果如下图:
小结
这种方式跟在MFC中使用Axtivex的MFC类比较类似,都是自己实例化一个控件,然后将这个控件添加到父类控件中,但是Esri提供的这个方式,也有自己的弊端,不能调试,只能在Release版本下运行,估计是这中方式需要的几个dll,没有提供Debug版本的,如果调试,那么程序会在我们实例化控件的地方跳出去,这个问题搞了我好几天,总找不到什么原因,借助伟大的Google,最后在Esri的英文论坛中也看到类似的,论坛中在求这个dll和相关lib的debug,看到这个,我也就明白了。
转载于:https://www.cnblogs.com/zuiyirenjian/archive/2013/01/04/2843682.html
Qt+ArcGIS Engine 10.1 开发(一)相关推荐
- ArcGIS Engine 10.2开发环境搭建
1.安装LicenseManager 2.安装Desktop 3.安装VS2012 4.安装Engine 5.安装ArcObject SDK for .NET
- ArcGIS Engine 10 开发常见问题的解决方法
ArcGIS Engine 10 开发常见问题的解决方法 You are not Licensed for 弹出提示框,点击确定,VS工程自动关闭 http://www.cnblogs.com/Ris ...
- ArcGIS Engine 10开发环境的一些常见问题(转载)
转自:http://bbs.esrichina-bj.cn/ESRI/viewthread.php?tid=107612&extra=&page=1 许多版友在刚刚使用ArcGIS 1 ...
- 【ArcGIS Engine二次开发】入门基础(2):ArcGIS开发方式(VBA、DLL、Add-in、Engine)对比
文章目录 2.1 使用VBA进行桌面软件开发 2.1.1 VBA开发方式 2.1.1 VBA代码的安全性 2.2 使用DLL进行桌面软件开发 2.2.1 DLL开发方式 2.2.2 DLL功能的应用部 ...
- 【ArcGIS Engine二次开发】入门基础(1):ArcGIS Engine简介及开发环境搭建
文章目录 ArcGIS Engine概述 ArcGIS Engine与ArcObjects的关系 ArcGIS Engine下载及安装 ArcGIS Engine概述 ArcGIS Engine简介 ...
- ArcGIS Engine 10.5下构建Java程序—轻松入门
虽然接触Engine Java的时间比较长,也接触过用户的一些问题,但是一般都是直接从ArcObjects SDK for Java的示例工程中找一个,然后测试用户代码,并没有自己动手搭建过Engin ...
- 利用Arcgis Engine 二次开发的使用和总结
Arcgis Engine 初体验 先放一张第一版系统的图,由于公司机密不能提供源码,但是各个小功能提供源码,为需要的同仁提供些许帮助. 接下来进入正题,将逐一展示利用Arcgis Engine开发的 ...
- 【转载】利用ArcGIS Engine 二次开发的使用和总结
文章目录 ArcGIS Engine 初体验 一.较完全编辑功能GIS程序 二.字段搜索要素和空间搜索要素GIS程序 三.图层重叠搜索GIS程序 四.要素合并.裁剪及检测要素重叠GIS程序 五.自定义 ...
- 《ArcGIS Engine+C#实例开发教程》第三讲 MapControl与PageLayoutControl同步
<ArcGIS Engine+C#实例开发教程>第三讲 MapControl与PageLayoutControl同步 原文:<ArcGIS Engine+C#实例开发教程>第三 ...
最新文章
- 【前沿】MIT搞了个进取型机器人!能研究学习对象操纵的基础
- mysql crash_Mysql 无故crash
- UBUNtu·E: 无法获得锁 /var/lib/apt/lists/lock - open (11: 资源暂时不可用) E: 无法对目录 /var/lib/apt/lists/ 加锁 问题解决方法
- app爬虫Android 7证书设置
- Java折叠_[Java教程]Jquery中菜单的展开和折叠
- Adobe AIR教程:面向iOS设备的原生扩展
- io字符流和字节流之间的转换和基本应用练习
- php文件之间传值的三种主流并且常用的方式
- Git储藏和引用日志
- Flutter 自定义弹幕展示样式
- python爬虫携带cookie访问QQ空间
- 海外邮件收发阻碍多?【企业邮箱怎么申请】
- 琵琶行用计算机弹,琵琶行三次弹
- Python_day04
- UI设计中面性图标设计总结
- 【推荐】献给在这个世界上摇摆不定的朋友们
- 【用es6写个机选彩票】
- 【最近抖音上元宇宙虚拟项目七国争霸,直播互动游戏源码解析】
- Oracle10g ora12170,ORA-3136、TNS-12535 12170 12606
- 美团,大众点评,58城市行政区域和商圈数据实现
热门文章
- openwrt gpio控制与使用
- VMware 提示”此虚拟机被配置为64位操作系统,然而,64位操作无法进行”
- [react] 怎样将事件传递给子组件?
- react学习(47)----react中initialValue和value不能一起定义
- 前端学习(3130):react-hello-react之回调形式的createRef
- 前端学习(3105):react-hello-jsx语法规则
- [html] 如何实现默认显示git的第一帧图片,当鼠标经过时,播放完整的gif动画
- [css] 当拿到一个新的项目,让你对这个项目的css做下架构设计,你该如何下手?
- 前端学习(2818):小程序学习之文件建立
- 前端学习(2358):v-bind和v-for