Qt+ArcGIS Engine 10.1 开发(一)

 

 

Qt作为一个跨平台C++图形用户界面应用程序开发框架,相当于微软的MFC(只能运行在Windows平台上),Qt命运多舛,几经易主,现在属于芬兰IT服务公司Digia。

  1. 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,所以要单独下载。

 

  1. Qt的第一个程序

安装完后,需要配置几个环境变量,QMAKESPE(根据自己的情况配置,因为我用的是VS2010,所有配置win32-msvc2010),如下图:

QTDIR(Qt的安装目录),如下图:

在Path中添加Qt的bin目录如下图:

打开VS2010,新建工程可以找到Qt4 的模板:

 

 

完成之后,在VS中运行,出现下面的界面,因为我们什么都没做,在弹出的界面上什么都没有,不过没关系,只要能出现,就说明我们的Qt已经可以使用了,如下图:

 

  1. ArcGIS Engine的环境

安装ArcGIS ArcObjects for Cross Platform C++ 的SDK,这个没有什么好说的。

  1. 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();

}

 

运行后可以看到下面的效果

 

  1. ArcGIS Engine+Qt(GUI开发)

在MFC中我们介绍了两种开发GUI的方法,一种是通过生成相应的Activex控件MFC类,另一种是通过插入Activex控件的方法,在Qt里面做GUI的AE开发,也有两种不同的做法,而这两种做法需要引入的头文件也有差异,除了头文件的差异,我们需要配置额外的信息,在这里我们分别对两种方法介绍。

  1. ArcGIS Engine+Qt(GUI开发,使用Esri提供的控件类)

    1. 额外的配置

对于这种方法,需要配置很多信息,在工程项目的连接器的常规中找到SDK的lib目录(在MFC的开发中,我们应该没有这个步骤),如下图:

 

在附加依赖项中输入qt4ctl.lib和aoctl.lib文件如下图:

 

此外还要在环境变量中配置Path(不一定要在Path中配置,只要在运行的时候能找到相应的文件即可),要不然在运行的时候会报下面的错误,如下图:

 

这是因为Qt的AE在运行的时候用到了Engine安装目录下的bin下的三个文件:Qt4ctl.dll, aoctl.dll, ctlbase.dll,只要将Engine的bin目录配置到Path中就可以了,如下图:

  1. 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);

};

  1. 代码编写

我们将这种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);

}

 

 

运行效果如下图:

  1. 小结

这种方式跟在MFC中使用Axtivex的MFC类比较类似,都是自己实例化一个控件,然后将这个控件添加到父类控件中,但是Esri提供的这个方式,也有自己的弊端,不能调试,只能在Release版本下运行,估计是这中方式需要的几个dll,没有提供Debug版本的,如果调试,那么程序会在我们实例化控件的地方跳出去,这个问题搞了我好几天,总找不到什么原因,借助伟大的Google,最后在Esri的英文论坛中也看到类似的,论坛中在求这个dll和相关lib的debug,看到这个,我也就明白了。

转载于:https://www.cnblogs.com/zuiyirenjian/archive/2013/01/04/2843682.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/422012.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c语言 返回函数是结构体指针变量,一个函数返回值为指向结构体的指针的问题...

一个函数返回值为指向结构体的指针的问题#include #include struct student{int num;char name[10];struct student *next;}struct student *creat(int x) //这里不知道为什么错&#xff1f;&#xff1f;{struct student *head,*p,*q;int i;for(i0;i{p(struct student*)malloc(…

分享30个新鲜PSD网站模板免费下载

Web 设计始终是设计师充满挑战性的工作。他们需要的专业技能和与的伟大想法&#xff0c;来完成一个设计良好的网站。某个时候设计师需要帮助几个免费的资源&#xff0c;以使工作更轻松。这篇文章是一个完美的解决方案&#xff0c;为网站设计的资源。在这里我们目前 30 新鲜 PSD…

C语言编程快速入门黎明,何用C语言模拟键盘输入?

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼static char szUnd[] "_______ __ ____ _____ ______ ______ ___ _______ ______";//在窗口中输出文字作为信息标题HDC hdc;PAINTSTRUCT ps;TEXTMETRIC tm;switch (iMsg){case WM_CREATE://处理窗口创建的消息hdc GetDC…

如何创建基本的高级队列之一:创建发送方代码

/* 基本组成 发送方&#xff08;DB1&#xff09;&#xff1a; Queue type &#xff1a;决定发送消息的类型 Queue table &#xff1a;消息发送的载体 Queue &#xff1a;队列 Subscriber &#xff1a;订购者&#xff0c;同一个队列可以有n个订购者 Propagation &#xff1a;传播…

c语言编程 float p,C语言编程经典例题

学习c语言编程的实战例题,非常典型的题目&#xff1a;编写一个函数&#xff0c;输入n为偶数时&#xff0c;调用函数求1/21/4...1/n,当输入n为奇数时&#xff0c;调用函数1/11/3...1/n(利用指针函数)1.程序分析&#xff1a;2.程序源代码&#xff1a;#include “stdio.h“ float …

c语言mergesort 参数,归并排序C语言兑现MergeSort

归并排序C语言实现MergeSort是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divideand Conquer)的一个非常典型的应用。算法伪码&#xff1a;MERGE-SORT(A&#xff0c;p, r)if p < rthen q (p r) / 2MERGE-SORT(A&#xff0c;p, q)MERGE-SORT(A&#xff0c…

WPF中打印问题的探讨[转]

转自&#xff1a;http://blog.sina.com.cn/s/blog_624dc0120100ld6m.html 最近在做一个WPF方面的项目&#xff0c;在打印功能实现上费了很大劲。因为我原来是在做Winform方面的项目&#xff0c;接受WPF时感觉还很相似&#xff0c;可仔细往里做下去却发现两者外看相似&#xff0…

语法分析树(先看例子再看定义)

语法分析树&#xff08;先看例子再看定义&#xff09; 先讲例子 书上讲问题&#xff0c;先讲定义&#xff0c;一顿学术操作&#xff0c;让人云里雾里&#xff0c;然后出例子。其实这样往往让人觉得看书的过程就是放弃的过程。 关于语法分析树&#xff0c;我先从上篇文章的例…

C语言正函数nosign,C语言标准库函数查询手册.docx

球锣宜软瘠旱塾3abort功能异常终止程序头文件StdIib.h语法VOid abort(void);abs功能整数的绝对值头文件StdIib.h语法int abs(int: j);返回值整数j的绝对值。如果不能表示J的绝对值&#xff0c;那么函数的行为是未定义的。absread功能读磁盘绝对扇区函数头文件dos ? h语法int a…

spring 实例化bean的几种方法

1.普通的通过构造函数初始化&#xff0c;没有指定构造函数参数的就是用默认的无参的构造方法 <bean id"exampleBean" class"examples.ExampleBean"/><bean name"anotherExample" class"examples.ExampleBeanTwo"/> 构造函…

middle函数C语言,C语言函数调用栈(三)

6 调用栈实例分析本节通过代码实例分析函数调用过程中栈帧的布局、形成和消亡。6.1 栈帧的布局示例代码如下&#xff1a;//StackReg.c#include //获取函数运行时寄存器%ebp和%esp的值#define FETCH_SREG(_ebp, _esp) do{\asm volatile( \"movl %%ebp, %0 \n" \"…

c语言多个形参,C中子函数最多有几个形参

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼C89 31个&#xff0c;C99 127个。ANSI C892.2.4.1 Translation limitsThe implementation shall be able to translate and execute at least one program that contains at least one instance of every one of the following lim…

什么叫ERP软件

1.ERP是什么&#xff1f; erp是个管理系统&#xff01;是一个成套的统称&#xff01;构成&#xff1a;进销存BOM生产MRP质检(IQC/FQC/PQC)车间日报/简单排产应收应付固定资产实际成本算法自动财务。就是通过软件管理&#xff0c;实现最小的库存和最大的利益&#xff01; 2.什么…

android 杀 服务器,android busybox httpd搭建简单web服务器

安卓手机利用busybox中的httpd命令可以创建一个简单的web服务器。我们可以在终端模拟器中输入一下命令查看httpd的使用帮助。busybox httpd --help1|u0_a84cancro:/ $ busybox httpd --helpBusyBox v1.20.2-MIUI (2012-08-20 20:59:32 CST) multi-call binary.Usage: httpd [-i…

sublimeclang里面使用相对路径

在sublime的project里面&#xff0c;可以添加sublimeclang的options,比如这样 {"folders":[{"path": "/C/EverBox/gitCode/clangxx"}],"settings": {"sublimeclang_options": ["-Wall","-IC:\\EverBox\\gitC…

短信恢复 android,苹果手机短信恢复:安卓+苹果手机短信恢复教程,必须收藏!...

原标题&#xff1a;苹果手机短信恢复&#xff1a;安卓苹果手机短信恢复教程&#xff0c;必须收藏&#xff01;手机短信怎么恢复&#xff1f;日常生活中&#xff0c;大家或多或少会不小心把删除一些不必要的短信&#xff0c;比如注册某软件的验证码的短信&#xff0c;面试通知地…