如何免费建设自己稳定的网站,站长工具国色天香,在线画画,2345电脑版网址导航Qt作为一个跨平台C图形用户界面应用程序开发框架#xff0c;相当于微软的MFC(只能运行在Windows平台上)#xff0c;Qt命运多舛#xff0c;几经易主#xff0c;现在属于芬兰IT服务公司Digia。 Qt环境安装 Qt的最新版本是Qt5.0,该版本是在12月中旬发布的#xff0c;在这里我… 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如下图 QTDIRQt的安装目录如下图 在Path中添加Qt的bin目录如下图 打开VS2010新建工程可以找到Qt4 的模板 完成之后在VS中运行出现下面的界面因为我们什么都没做在弹出的界面上什么都没有不过没关系只要能出现就说明我们的Qt已经可以使用了如下图 ArcGIS Engine的环境 安装ArcGIS ArcObjects for Cross Platform C 的SDK这个没有什么好说的。 ArcGIS EngineQt控制台开发 安装了SDK之后我们就需要将ArcGIS Engine的类库等引入到开发环境中在Qt中引入ArcGIS Engine的类库等信息.在新建立的Qt控制台程序工程右键找到C/C然后找到常规在右侧的附加包含目录中输入下面三个目录的地址因为我的有x(86)所以出现了下面的特殊符号 说明在MFC中我们除了引入三个目录地址还配置了预处理器定义ESRI_WINDOW在这里我并没有配置。 配置好这个之后在主程序文件中输入代码这个代码我在这里就不做解释到时候可以看这个文档的姊妹篇- 《VC2010ArcGIS 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 , L10.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_strD:\\guest\\chinasimplify; bstr_str SysAllocString(q_str.utf16()); HRESULT hripWorkspaceFactory-OpenFromFile(bstr_str,0,pWs); SysFreeString(bstr_str); QString q_str1china_simply.shp; BSTR bStringWSSysAllocString(q_str1.utf16()); if (FAILED(hr)) { return 0; } #pragma endregion #pragma region QI 这里和NET下不一样 IFeatureWorkspacePtr ipRastWork (pWs); #pragma endregion #pragma region 打开要素类并获取个数 IFeatureClassPtr pFtClass; hripRastWork-OpenFeatureClass(bStringWS,pFtClass); SysFreeString(bStringWS); if (FAILED(hr)) { return 0; } long pCount0; pFtClass-FeatureCount(NULL,pCount); #pragma endregion QString s QString::number(pCount, 10); QTextStream cout(stdout); couts endl; QString str; QTextStream in(stdin); in str; return a.exec(); } 运行后可以看到下面的效果 ArcGIS EngineQtGUI开发 在MFC中我们介绍了两种开发GUI的方法一种是通过生成相应的Activex控件MFC类另一种是通过插入Activex控件的方法在Qt里面做GUI的AE开发也有两种不同的做法而这两种做法需要引入的头文件也有差异除了头文件的差异我们需要配置额外的信息在这里我们分别对两种方法介绍。 ArcGIS EngineQtGUI开发使用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这个例子我只将TOCMap和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 , L10.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 LesriControlCommands.ControlsOpenDocCommand; pToolbar-AddItem(varTool, 0, -1, VARIANT_FALSE, 0, esriCommandStyleIconOnly, itemindex); varTool LesriControlCommands.ControlsAddDataCommand; pToolbar-AddItem(varTool, 0, -1, VARIANT_FALSE, 0, esriCommandStyleIconOnly, itemindex); varTool LesriControlCommands.ControlsMapZoomInTool; pToolbar-AddItem(varTool, 0, -1, VARIANT_TRUE, 0, esriCommandStyleIconOnly, itemindex); varTool LesriControlCommands.ControlsMapZoomOutTool; pToolbar-AddItem(varTool, 0, -1, VARIANT_FALSE, 0, esriCommandStyleIconOnly, itemindex); varTool LesriControlCommands.ControlsMapZoomInFixedCommand; pToolbar-AddItem(varTool, 0, -1, VARIANT_FALSE, 0, esriCommandStyleIconOnly, itemindex); varTool LesriControlCommands.ControlsMapZoomOutFixedCommand; pToolbar-AddItem(varTool, 0, -1, VARIANT_FALSE, 0, esriCommandStyleIconOnly, itemindex); varTool LesriControlCommands.ControlsMapPanTool; pToolbar-AddItem(varTool, 0, -1, VARIANT_FALSE, 0, esriCommandStyleIconOnly, itemindex); varTool LesriControlCommands.ControlsMapFullExtentCommand; pToolbar-AddItem(varTool, 0, -1, VARIANT_FALSE, 0, esriCommandStyleIconOnly, itemindex); varTool LesriControlCommands.ControlsMapZoomToLastExtentBackCommand; pToolbar-AddItem(varTool, 0, -1, VARIANT_FALSE, 0, esriCommandStyleIconOnly, itemindex); varTool LesriControlCommands.ControlsMapZoomToLastExtentForwardCommand; pToolbar-AddItem(varTool, 0, -1, VARIANT_FALSE, 0, esriCommandStyleIconOnly, itemindex); varTool LesriControlCommands.ControlsSelectFeaturesTool; pToolbar-AddItem(varTool, 0, -1, VARIANT_FALSE, 0, esriCommandStyleIconOnly, itemindex); varTool LesriControlCommands.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