PIESDK二次开发——C++(QT)组件式二次开发
- 新建Q tWidgets Application工程,选中Debug(Core,GUI,Widgets),然后点击 next -> finish;
- 配置环境
(1)在工程文件夹下,新建(myApp)文件夹,然后将PIESDK中的Debug_x64以及config文件夹复制到新建文件夹下,删除Debug_x64下多余内容(保留dll文件以及所有文件夹内容即可)
(2)属性 —— 常规 ——输出目录:选择…\MyApp\Debug_x64
(3)属性——c/c++——附加包含目录:选择PIESDK下的include,ThirdPartyLib\boost\include
我的路径如下:
D:\PIESDK_C\PIESDK\ThirdPartyLib\boost\include
D:\PIESDK_C\PIESDK\Include\Core
D:\PIESDK_C\PIESDK\Include
(注意:如果QT不能用,配置一下QT)
D:\QT\5.9.4\msvc2015_64\include
(4)属性 —— 连接器——常规——附加库目录:选择PIESDK下的lib文件
我的路径如下:
D:\PIESDK_C\PIESDK\Lib
D:\QT\5.9.4\msvc2015_64\lib
(在这里我同样配置了Qt的文件)
(5)属性 —— 连接器——输入——附加依赖项,内容如下:
qtmaind.lib
Qt5Cored.lib
Qt5Guid.lib
Qt5Widgetsd.lib
SysAdapterUID.lib
SysAlgoD.lib
SysCartoD.lib
SysDataSourceD.lib
SysDisplayD.lib
SysFrameworkD.lib
SysGeometryD.lib
SysUID.lib
SysUtilityD.lib
- 设计ui界面
这里,我主要拉了一个Dock Widget 和 tab Widget用于存放控件,在菜单上增加一个FILE——OPEN按钮
之后我们打开命令行,进入到工程路径即(.ui)文件所在路径,输入uic -o xxx.h aaa.ui (其中.h文件随便命名我一般命名为:ui的名字在加上_designer,如aaa_designer),我的ui转为.h文件后,内容如下:
// PIE_CML_QT_Designer.h
/********************************************************************************
** Form generated from reading UI file 'PIE_CML_QT.ui'
**
** Created by: Qt User Interface Compiler version 5.9.7
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/
#ifndef PIE_CML_QT_DESIGNER_H
#define PIE_CML_QT_DESIGNER_H
#include <QtCore/QVariant>
#include <QtWidgets/QAction>
#include <QtWidgets/QApplication>
#include <QtWidgets/QButtonGroup>
#include <QtWidgets/QDockWidget>
#include <QtWidgets/QHeaderView>
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QMenu>
#include <QtWidgets/QMenuBar>
#include <QtWidgets/QStatusBar>
#include <QtWidgets/QTabWidget>
#include <QtWidgets/QToolBar>
#include <QtWidgets/QWidget>
QT_BEGIN_NAMESPACE
class Ui_PIE_CML_QTClass
{
public:
QAction *actionOPEN;
QWidget *centralWidget;
QTabWidget *tabWidget;
QWidget *tab;
QWidget *tab_2;
QMenuBar *menuBar;
QMenu *menuFILE;
QToolBar *mainToolBar;
QStatusBar *statusBar;
QDockWidget *dockWidget;
QWidget *dockWidgetContents;
void setupUi(QMainWindow *PIE_CML_QTClass)
{
if (PIE_CML_QTClass->objectName().isEmpty())
PIE_CML_QTClass->setObjectName(QStringLiteral("PIE_CML_QTClass"));
PIE_CML_QTClass->resize(1077, 745);
actionOPEN = new QAction(PIE_CML_QTClass);
actionOPEN->setObjectName(QStringLiteral("actionOPEN"));
centralWidget = new QWidget(PIE_CML_QTClass);
centralWidget->setObjectName(QStringLiteral("centralWidget"));
tabWidget = new QTabWidget(centralWidget);
tabWidget->setObjectName(QStringLiteral("tabWidget"));
tabWidget->setGeometry(QRect(0, 0, 811, 681));
tabWidget->setLayoutDirection(Qt::LeftToRight);
tabWidget->setAutoFillBackground(false);
tab = new QWidget();
tab->setObjectName(QStringLiteral("tab"));
tabWidget->addTab(tab, QString());
tab_2 = new QWidget();
tab_2->setObjectName(QStringLiteral("tab_2"));
tabWidget->addTab(tab_2, QString());
PIE_CML_QTClass->setCentralWidget(centralWidget);
menuBar = new QMenuBar(PIE_CML_QTClass);
menuBar->setObjectName(QStringLiteral("menuBar"));
menuBar->setGeometry(QRect(0, 0, 1077, 26));
menuFILE = new QMenu(menuBar);
menuFILE->setObjectName(QStringLiteral("menuFILE"));
PIE_CML_QTClass->setMenuBar(menuBar);
mainToolBar = new QToolBar(PIE_CML_QTClass);
mainToolBar->setObjectName(QStringLiteral("mainToolBar"));
PIE_CML_QTClass->addToolBar(Qt::TopToolBarArea, mainToolBar);
statusBar = new QStatusBar(PIE_CML_QTClass);
statusBar->setObjectName(QStringLiteral("statusBar"));
PIE_CML_QTClass->setStatusBar(statusBar);
dockWidget = new QDockWidget(PIE_CML_QTClass);
dockWidget->setObjectName(QStringLiteral("dockWidget"));
dockWidgetContents = new QWidget();
dockWidgetContents->setObjectName(QStringLiteral("dockWidgetContents"));
dockWidget->setWidget(dockWidgetContents);
PIE_CML_QTClass->addDockWidget(static_cast<Qt::DockWidgetArea>(1), dockWidget);
menuBar->addAction(menuFILE->menuAction());
menuFILE->addAction(actionOPEN);
retranslateUi(PIE_CML_QTClass);
tabWidget->setCurrentIndex(0);
QMetaObject::connectSlotsByName(PIE_CML_QTClass);
} // setupUi
void retranslateUi(QMainWindow *PIE_CML_QTClass)
{
PIE_CML_QTClass->setWindowTitle(QApplication::translate("PIE_CML_QTClass", "PIE_CML_QT", Q_NULLPTR));
actionOPEN->setText(QApplication::translate("PIE_CML_QTClass", "OPEN", Q_NULLPTR));
tabWidget->setTabText(tabWidget->indexOf(tab), QApplication::translate("PIE_CML_QTClass", "Tab 1", Q_NULLPTR));
tabWidget->setTabText(tabWidget->indexOf(tab_2), QApplication::translate("PIE_CML_QTClass", "Tab 2", Q_NULLPTR));
menuFILE->setTitle(QApplication::translate("PIE_CML_QTClass", "FILE", Q_NULLPTR));
} // retranslateUi
};
namespace Ui {
class PIE_CML_QTClass: public Ui_PIE_CML_QTClass {};
} // namespace Ui
QT_END_NAMESPACE
#endif // PIE_CML_QT_DESIGNER_H
- 编写代码
在你新建的工程下面会有一个 (工程名.h)、(工程名.cpp)、(main.cpp)文件,我们可以直接在(工程名.h)和(工程名.cpp)上编写代码,也可以自己新建一个Qt类,然后编写代码。
接下来,我们先看看 (工程名.h)、(工程名.cpp)以及(main.cpp)文件内的内容:(我的工程名为:PIE_CML_QT
// PIE_CML_QT.h
#pragma once
#include <QtWidgets/QMainWindow>
#include "ui_PIE_CML_QT.h"
class PIE_CML_QT : public QMainWindow
{
Q_OBJECT
public:
PIE_CML_QT(QWidget *parent = Q_NULLPTR);
private:
Ui::PIE_CML_QTClass ui;
};
// PIE_CML_QT.cpp
#include "PIE_CML_QT.h"
PIE_CML_QT::PIE_CML_QT(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
}
// main.cpp
#include "MainWindowTest.h"
#include <QtWidgets/QApplication>
//#include "CML_PIESDK.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
PIE_CML_QT w;
w.show();
return a.exec();
}
PIE_CML_QT.h文件中有一句#include “ui_PIE_CML_QT.h”,但是我们发现,我们并找不到这个.h文件,其实,他是系统自动生成的一个ui文件的.h文件,代码是不可见的,(或许在qt里面能够看见),在这里,我们为了所有代码可见,将#include “ui_PIE_CML_QT.h”,改成我们上面生成的PIE_CML_QT_Designer.h文件,当然在这之前,我们需要把他加进来,即添加——现有项——选中文件点击确定即可,更改后代码如下:
// PIE_CML_QT.h
#pragma once
#include <QtWidgets/QMainWindow>
#include "PIE_CML_QT_Designer.h"
class PIE_CML_QT : public QMainWindow
{
Q_OBJECT
public:
PIE_CML_QT(QWidget *parent = Q_NULLPTR);
private:
Ui::PIE_CML_QTClass ui;
};
在这里我选择新建一个Qt类来完成代码的编写
- 右键单击项目——添加——Add Qt Class … ——选中Qt Class (命名:MainWindowTest)——add 之后全面默认即可;
将生成MainWindowTest.h和MainWindowTest.cpp两个文件,内容分别如下:
// MainWindowTest.h
#pragma once
#include <QObject>
class MainWindowTest : public QObject
{
Q_OBJECT
public:
MainWindowTest(QObject *parent);
~MainWindowTest();
};
// MainWindowTest.cpp
#include "MainWindowTest.h"
MainWindowTest::MainWindowTest(QObject *parent)
: QObject(parent)
{
}
MainWindowTest::~MainWindowTest()
{
}
更改MainWindowTest.h和MainWindowTest.cpp两个文件内容,更改后内容如下:
// MainWindowTest.h
#pragma once
#include <QtWidgets/QMainWindow>
#include "SysAdapterUI/TOCControl.h"
#include "SysAdapterUI/MapControl.h"
#include "SysAdapterUI/PageLayoutControl.h"
#include "MainWindowTest_Designer.h"
class MainWindowTest : public QMainWindow
{
Q_OBJECT
public:
MainWindowTest(QWidget *parent = Q_NULLPTR);
private:
//MyUi::MainWindowsForm mui;
Ui::MainWindow ui;
/**
* @brief 图层树控件
*/
SysAdapterUI::TOCControl* m_pTOCControl;
/**
* @brief 地图控件
*/
SysAdapterUI::MapControl* m_pMapControl;
/**
* @brief 制图控件
*/
SysAdapterUI::PageLayoutControl* m_pPageLayoutControl;
/**
* @brief 当前激活控件
*/
SysCarto::IPmdContents* m_pCurrentControl;
private:
void On_ActionAddRasterData_Triggered();
};
// MainWindowTest.cpp
#include "MainWindowTest.h"
#include "AddRasterDataCommand.h"
MainWindowTest::MainWindowTest(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
//mui.setupUi(this);
m_pTOCControl = new SysAdapterUI::TOCControl();
ui.dockWidget->setWidget(m_pTOCControl);
m_pMapControl = new SysAdapterUI::MapControl();
m_pPageLayoutControl = new SysAdapterUI::PageLayoutControl();
ui.tabWidget->addTab(m_pMapControl, tr("地图模式"));
ui.tabWidget->addTab(m_pPageLayoutControl, tr("制图模式"));
SysCarto::MapPtr ptrMap = m_pPageLayoutControl->GetMap();
ptrMap->SetName("Map");
m_pTOCControl->SetBuddy(m_pPageLayoutControl);
m_pMapControl->SetMap(ptrMap);
connect(ui.actionOPEN, &QAction::triggered, this, &MainWindowTest::On_ActionAddRasterData_Triggered);
// 激活控件
//m_pPageLayoutControl->GetActiveView()->DeActivate();
//m_pMapControl->GetActiveView()->Activate(ui.tabWidget->currentWidget());
//m_pCurrentControl = m_pMapControl;
};
void MainWindowTest::On_ActionAddRasterData_Triggered() {
SysUI::ICommandPtr ptrCmd = new AddRasterDataCommand();
if (ptrCmd == nullptr) return;
ptrCmd->OnCreate(m_pMapControl);
ptrCmd->OnClick();
}
这里要注意#include “AddRasterDataCommand.h”,以及void MainWindowTest::On_ActionAddRasterData_Triggered()里面的代码,AddRasterDataCommand为我自己写的一个功能测试插件(加载栅格数据插件),在这里你可以将其换成你自己的并更改相应代码,或者直接在On_ActionAddRasterData_Triggered函数体内实现你想实现的功能即可
- 最后更改mian.cpp文件,内容如下
// main.cpp
#include "MainWindowTest.h"
#include <QtWidgets/QApplication>
//#include "CML_PIESDK.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindowTest w;
w.show();
return a.exec();
}
接下来我展示一下我们的AddRasterDataCommand.h以及AddRasterDataCommand.cpp文件的内容:
// AddRasterDataCommand.h
#ifndef ADDRASTERDATACOMMAND_H
#define ADDRASTERDATACOMMAND_H
#include <QObject>
#include "SysFramework/BaseCommand.h"
class AddRasterDataCommand : public SysFramework::BaseCommand
{
public:
AddRasterDataCommand();
~AddRasterDataCommand();
virtual void OnClick() override;
};
#endif // ADDRASTERDATACOMMAND_H
// AddRasterDataCommand.cpp
#include <QString>
#include <QFileDialog>
#include "SysCarto/LayerFactory.h"
#include "SysDataSource/DatasetFactory.h"
#include "SysDataSource/MultiDataset.h"
#include "SysGeometry/SpatialReferenceFactory.h"
#include "AddRasterDataCommand.h"
AddRasterDataCommand::AddRasterDataCommand()
{
}
AddRasterDataCommand::~AddRasterDataCommand()
{
}
void AddRasterDataCommand::OnClick()
{
QString filter = "栅格数据 (*.tif)";
QStringList lstFile = QFileDialog::getOpenFileNames(nullptr, "添加数据", "", filter);
if (lstFile.count() < 1) return;
for each (QString _file in lstFile)
{
SysDataSource::DatasetPtr datasetPtr = SysDataSource::DatasetFactory::Instance()->OpenDataset(_file, SysDataSource::OpenMode::GA_ReadOnly);
if (datasetPtr != nullptr)
{
SysDataSource::RasterDatasetPtr rasterDatasetPtr = static_cast<SysDataSource::RasterDatasetPtr>(datasetPtr);
SysCarto::LayerPtr layerPtr = SysCarto::LayerFactory::Instance()->CreateDefaultRasterLayer(rasterDatasetPtr);
m_ptrHookHelper->GetFocusMap()->AddLayer(layerPtr);
}
m_ptrHookHelper->GetActiveView()->Refresh();
}
}
当然,如果你足够熟悉Qt,是完全可以直接通过代码实现其全部设计过程的,在这里我新建了一个名为CML_PIESDK的Qt类,一个.ui文件,并生成其.h(PIE_CML_QT1.h)这里的.h文件完全可以不用生成,因为我们不在需要查看里面的代码了,当然前提是你要知道你新建的那个.ui的命名空间和类名,通过.h文件是可以看到的,前面已经有过.h文件的代码,我就不重复粘贴了,接下来我将展示一下CML_PIESDK.h和CML_PIESDK.cpp的代码:
// CML_PIESDK.h
#pragma once
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QDockWidget>
#include <QtWidgets/QLabel>
#include <QtWidgets/QComboBox>
#include <QtWidgets/QLineEdit>
#include "SysAdapterUI/TOCControl.h"
#include "SysAdapterUI/MapControl.h"
#include "SysAdapterUI/PageLayoutControl.h"
#include "PIE_CML_QT1.h"
class CML_PIESDK : public QMainWindow
{
Q_OBJECT
public:
/**
* @brief 构造函数
* @return
*/
CML_PIESDK(QWidget *parent = Q_NULLPTR);
/**
* @brief 析构函数
* @return
*/
~CML_PIESDK();
private:
Ui::PIE_CML_QTClass ui;
/**
* @brief TOCDockWidget
*/
QDockWidget* m_pDockWidget_TOC;
/**
* @brief TabWidget控件
*/
QTabWidget* m_pTabWidgetMain;
/**
* @brief 图层树控件
*/
SysAdapterUI::TOCControl* m_pTOCControl;
/**
* @brief 地图控件
*/
SysAdapterUI::MapControl* m_pMapControl;
/**
* @brief 制图控件
*/
SysAdapterUI::PageLayoutControl* m_pPageLayoutControl;
/**
* @brief 当前激活控件
*/
SysCarto::IPmdContents* m_pCurrentControl;
public:
//void On_TabWidget_CurrentChanged(int index);
void On_ActionAddRasterData_Triggered(bool checked);
};
// CML_PIESDK.cpp
#include "CML_PIESDK.h"
#include <QtWidgets/QTabWidget>
#include <QtGui/QKeySequence>
#include <QtWidgets/QLabel>
#include "SysUI/CMDPluginModule.h"
#include "SysUI/ICommand.h"
#include "SysGeometry/SpatialReference.h"
CML_PIESDK::CML_PIESDK(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
// 添加图层树控件
m_pDockWidget_TOC = new QDockWidget(tr("图层树"), this, Qt::Widget);
m_pDockWidget_TOC->setFeatures(QDockWidget::NoDockWidgetFeatures | QDockWidget::DockWidgetFeature::DockWidgetClosable);
m_pDockWidget_TOC->setMinimumWidth(280);
m_pDockWidget_TOC->setMaximumWidth(420);
this->addDockWidget(Qt::DockWidgetArea::LeftDockWidgetArea, m_pDockWidget_TOC);
m_pTOCControl = new SysAdapterUI::TOCControl(m_pDockWidget_TOC);
m_pDockWidget_TOC->setWidget(m_pTOCControl);
// 添加地图和制图控件
m_pTabWidgetMain = new QTabWidget(this);
this->setCentralWidget(m_pTabWidgetMain);
m_pMapControl = new SysAdapterUI::MapControl(this);
m_pPageLayoutControl = new SysAdapterUI::PageLayoutControl(this);
m_pMapControl->installEventFilter(this);
m_pPageLayoutControl->installEventFilter(this);
m_pTabWidgetMain->addTab(m_pMapControl, tr("地图模式"));
m_pTabWidgetMain->addTab(m_pPageLayoutControl, tr("制图模式"));
m_pTabWidgetMain->setTabPosition(QTabWidget::South);
//connect(m_pTabWidgetMain, &QTabWidget::currentChanged, this, &CML_PIESDK::On_TabWidget_CurrentChanged);
// 三大控件地图同步
SysCarto::MapPtr ptrMap = m_pPageLayoutControl->GetMap();
ptrMap->SetName("Map");
m_pTOCControl->SetBuddy(m_pPageLayoutControl);
m_pMapControl->SetMap(ptrMap);
// 激活控件
m_pPageLayoutControl->GetActiveView()->DeActivate();
m_pMapControl->GetActiveView()->Activate(m_pTabWidgetMain->currentWidget());
m_pCurrentControl = m_pMapControl;
QMenu* pMenu_File = this->menuBar()->addMenu(tr("文件(&F)"));
QAction* pAction_AddRasterData = pMenu_File->addAction(tr("打开栅格数据"));
pAction_AddRasterData->setShortcut(QKeySequence("Ctrl+O"));
pMenu_File->addSeparator();
connect(pAction_AddRasterData, &QAction::triggered, this, &CML_PIESDK::On_ActionAddRasterData_Triggered);
}
CML_PIESDK::~CML_PIESDK() {
}
void CML_PIESDK::On_ActionAddRasterData_Triggered(bool checked)
{
//SysUI::ICommandPtr ptrCmd = new AddRasterDataCommand();
//if (ptrCmd == nullptr) return;
//ptrCmd->OnCreate(m_pCurrentControl);
//ptrCmd->OnClick();
}
整个工程下载地址:https://download.csdn.net/download/m0_45074715/22001481