PIESDK二次开发——C++(QT)组件式二次开发

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

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
C语言中可以使用宏定义来进行可视化操作。所谓宏定义,即使用预处理指令#define来定义一些代码块,在编译时会将这些定义进行替换操作。 对于可视化宏定义,可以通过使用宏函数来实现。宏函数是一种带有参数的宏定义,可以用于定义一些简单的表达或逻辑操作。通过预处理器,在程序编译之前将宏函数的调用处替换为相应的代码块。 例如,我们可以定义一个用于交换两个变量的宏函数SWAP: #define SWAP(a, b) {\ typeof(a) temp = a;\ a = b;\ b = temp;\ } 这样,我们在代码中可以直接使用SWAP函数进行变量交换,而不需要写额外的交换代码。 在可视化宏定义中,我们可以使用条件编译来实现代码的控制流。通过#if、#elif、#else和#endif等预处理指令,我们可以根据条件判断来选择性地替换代码块。 例如,我们可以定义一个宏函数MAX,用于返回两个数中的较大值: #define MAX(a, b) (a > b ? a : b) 在程序中,我们可以根据需要调用MAX函数来进行比较求值。这样,我们既可以实现了简洁的代码书写,又能够增加程序的可读性和维护性。 总而言之,通过宏定义,我们可以在C语言中实现一些简单的可视化操作。宏定义的使用可以大大简化代码编写和阅读的难度,提高代码的可维护性和可读性。但宏定义也有一些限制,例如对代码调试和错误处理不够友好,因此在使用宏定义时需要谨慎处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值