和处理。其中我用正则表达式过滤的一些无用标签。
代码是经过修改的,尽量通用化,理论上复制下来就能用。宏QTHQ_BASESHARED_EXPORT 删掉即可,原本是用于制作成dll的选项的,具体可以参考我的其它文章。
Qt制作dll(带ui)并调用,兼容32位和64位_redeclared without dllimport_大橘的博客-CSDN博客
hq_base_db_grid_excel.h:
/**************************************************************************************************
** File name: hq_base_db_grid_excel.h (HQ_Base_DB_Grid_Excel)
** Created by: Henrick.Nie at 2023-7-10
** Used for: Import/export the grid data from/to the excel file.
**************************************************************************************************/
#ifndef HQ_BASE_DB_GRID_EXCEL_H
#define HQ_BASE_DB_GRID_EXCEL_H
#include "qt-hq_base_global.h"
#include
#include
#include
#include
#include
#include
#include
#include "hq_base_db_grid.h"
class QTHQ_BASESHARED_EXPORT HQ_Base_DB_Grid_Excel
{
public:
static bool f_SaveToExcel(QTableWidget *oGrid,
const bool &bAskBeforeDoing, const bool &bAskBeforeOpenning, QString *sFilePath = nullptr,
QString *sErr = nullptr, const QString &sSheetName = QString());
static bool f_SaveToExcel(const QString &sExcelHtmlModel, QTableWidget *oGrid,
const bool &bAskBeforeDoing, const bool &bAskBeforeOpenning, QString *sFilePath = nullptr,
QString *sErr = nullptr, const QString &sSheetName = QString());
static bool f_GetFromExcel_AsXML(QString &sXML, QString *sErr = nullptr);
static bool f_GetFromExcel(const QString &sModel, QJsonArray &oArrRows, const bool &bFirstRowIsHeader = false, QString *sErr = nullptr);
static bool f_GetFromExcel(QTableWidget *oGrid, const bool &bFirstRowIsHeader = false, QString *sErr = nullptr);
static bool f_SetFirstRowToHeader(QTableWidget *oGrid, const bool &bSetHeader, QString *sErr = nullptr);
private:
static bool f_Grid_GetDataAsHtml(QTableWidget *oGrid, QString &sTableHtml, QString *sErr = nullptr);
static QString f_Grid_GetAlignByEnum(const int &iAlign);
static bool f_Excel_GetDataAsHtml(QString &sTableHtml, QString *sErr = nullptr);
};
#endif // HQ_BASE_DB_GRID_EXCEL_H
hq_base_db_grid_excel.cpp:
#include "hq_base_db_grid_excel.h"
/**================================================================================================
** Converts the grid data as the html table string, output it in the parameter 'sTableHtml'.
** Returns true on successed, otherwise returns false.
** ---------------------------------
** Format:
**
**
**
**
**
**
**
** f1
** f2
** f3
** f4
**
**
** 1
** 2
** 3
** 4
**
**
** a
** b
** c
** d
**
**
** cwd
** qwe
** xcz
** excz
**
**
**
**===============================================================================================*/
bool HQ_Base_DB_Grid_Excel::f_Grid_GetDataAsHtml(QTableWidget *oGrid, QString &sTableHtml, QString *sErr)
{
sTableHtml.clear();
if (nullptr == oGrid)
{
HQ_Base::f_Pointer_SetValue(sErr, QString("The grid is nullptr."));
return false;
}
//Indent
QString sTable_col, sTable_Rows_tr, sIndent_table = " ", sIndent_col = " ", sIndent_tr = " ", sIndent_td = " ";
//Headers and col info( )
sTable_Rows_tr.append(sIndent_tr + "\n");
QString sHeader_td;
for (int iCol = 0; iCol < oGrid->columnCount(); ++iCol)
{
//width
QString sCol_Width = QString::number(oGrid->columnWidth(iCol));
//align
QTableWidgetItem *item = oGrid->horizontalHeaderItem(iCol);
int iAlign = (nullptr == item) ? 0 : item->textAlignment();
QString sCol_Align = f_Grid_GetAlignByEnum(iAlign);
sTable_col.append(sIndent_col + " \n");
//header row
sHeader_td.append(sIndent_td + "" + oGrid->horizontalHeaderItem(iCol)->text() + " \n");
}
sTable_Rows_tr.append(sHeader_td);
sTable_Rows_tr.append(sIndent_tr + " \n");
//data( )
for (int iRow = 0; iRow < oGrid->rowCount(); ++iRow)
{
sTable_Rows_tr.append(sIndent_tr + "\n");
QString sRows_td;
for (int iCol = 0; iCol < oGrid->columnCount(); ++iCol)
{
QTableWidgetItem *item = oGrid->item(iRow, iCol);
QString sText;
if (nullptr != item)
{
sText = item->text();
}
sRows_td.append(sIndent_td + "" + sText + " \n");
}
sTable_Rows_tr.append(sRows_td);
sTable_Rows_tr.append(sIndent_tr + " \n");
}
//table
sTableHtml.append(sIndent_table + "\n");
sTableHtml.append(sTable_col);
sTableHtml.append(sTable_Rows_tr);
sTableHtml.append(sIndent_table + "
\n");
HQ_Base::f_Pointer_SetValue(sErr, QString());
return true;
}
QString HQ_Base_DB_Grid_Excel::f_Grid_GetAlignByEnum(const int &iAlign)
{
quint16 iHAlign = iAlign | 0x000F;
QString sAlign;
switch (iHAlign) {
case 1:
sAlign = "left";
break;
case 2:
sAlign = "right";
break;
case 4:
sAlign = "center";
break;
default:
break;
}
return sAlign;
}
/**================================================================================================
** Save the grid data to excel.
**===============================================================================================*/
bool HQ_Base_DB_Grid_Excel::f_SaveToExcel(QTableWidget *oGrid,
const bool &bAskBeforeDoing, const bool &bAskBeforeOpenning,
QString *sFilePath, QString *sErr, const QString &sSheetName)
{
try
{
//Get the model.
QString sFile = "excel_html.md";
QFile f(sFile);
if (!f.exists())
{
throw QString("Can not find the model file.");
}
if (!f.open(QIODevice::ReadOnly|QIODevice::Text))
{
if (f.isOpen())
{
f.close();
}
throw QString("The model file openning failed.");
}
QString sExcelHtml = f.readAll();
if (f.isOpen())
{
f.close();
}
return f_SaveToExcel(sExcelHtml, oGrid, bAskBeforeDoing, bAskBeforeOpenning, sFilePath, sErr, sSheetName);
}
catch (QString sExceptionMsg)
{
HQ_Base::f_Pointer_SetValue(sErr, sExceptionMsg);
return false;
}
}
bool HQ_Base_DB_Grid_Excel::f_SaveToExcel(const QString &sExcelHtmlModel, QTableWidget *oGrid,
const bool &bAskBeforeDoing, const bool &bAskBeforeOpenning,
QString *sFilePath, QString *sErr, const QString &sSheetName)
{
try
{
HQ_Base::f_Pointer_SetValue(sFilePath, QString());
HQ_Base::f_Pointer_SetValue(sErr, QString());
QString sExcelHtml = sExcelHtmlModel;
if (sExcelHtml.isEmpty())
{
throw QString("The excel model lost.");
}
if (nullptr == oGrid)
{
throw QString("The grid does not exist.");
}
QString sMsg;
//Ask user before doing.
if (bAskBeforeDoing)
{
sMsg = "Export the grid data to the excel. Continue?";
if(QMessageBox::question(nullptr, "", sMsg, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes) != QMessageBox::Yes)
{
return false;
}
}
//Select the saving path.
QString sFile_Saved = QFileDialog::getSaveFileName(nullptr, "Select the saving path.",
QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation),
"Excel (*.xlsx);;Excel 97-2003 (*.xls)");
if (sFile_Saved.isEmpty())
{
return false;//If the user canceled, do nothing.
}
//If the target file is not writable.
QFile f_Save(sFile_Saved);
if (f_Save.isOpen() || !f_Save.open(QIODevice::WriteOnly|QIODevice::Text))
{
if (f_Save.isOpen())
{
f_Save.close();
}
throw QString("The target file is using. Perhaps it is already openned by an other program.");
}
//Sheet name.
if (!sSheetName.isEmpty())
{
sExcelHtml.replace(QRegularExpression("(?<=)[\\s\\S]*(?= )"), sSheetName);
}
//Html_table.
QString sTableHtml;
if (!f_Grid_GetDataAsHtml(oGrid, sTableHtml, sErr))
{
return false;
}
sExcelHtml.replace(QRegularExpression(""), sTableHtml);
//Save to file.
qint64 i = f_Save.write(sExcelHtml.toStdString().c_str());
if (f_Save.isOpen())
{
f_Save.close();
}
if (i < 0)
{
throw QString("The file writting failed.");
}
//Ask before openning.
if (bAskBeforeOpenning)
{
sMsg = "The excel file exporting successed, open it?\n";
if(QMessageBox::question(nullptr, "", sMsg + sFile_Saved, QMessageBox::Yes|QMessageBox::No) == QMessageBox::Yes)
{
//Open the file.
QDesktopServices::openUrl(QUrl("file:///" + QDir::toNativeSeparators(sFile_Saved)));
}
}
HQ_Base::f_Pointer_SetValue(sFilePath, sFile_Saved);
HQ_Base::f_Pointer_SetValue(sErr, QString());
return true;
}
catch (QString sExceptionMsg)
{
HQ_Base::f_Pointer_SetValue(sFilePath, QString());
HQ_Base::f_Pointer_SetValue(sErr, sExceptionMsg);
return false;
}
}
/**================================================================================================
** Import the excel data to the html string, and output into the parameter 'sTableHtml'.
**===============================================================================================*/
bool HQ_Base_DB_Grid_Excel::f_Excel_GetDataAsHtml(QString &sTableHtml, QString *sErr)
{
try
{
sTableHtml.clear();
HQ_Base::f_Pointer_SetValue(sErr, QString());
QString sFileName = QFileDialog::getOpenFileName(nullptr, "Select the saving path.",
QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation),
"Excel (*.xlsx);;Excel 97-2003 (*.xls)");
if (sFileName.isEmpty())
{
return false;//If the user canceled, do nothing.
}
QFile f(sFileName);
if (!f.open(QIODevice::ReadOnly|QIODevice::Text))
{
if (f.isOpen())
{
f.close();
}
throw QString("The excel file openning failed.");
}
QString sExcelHtml = f.readAll();
if (f.isOpen())
{
f.close();
}
QRegularExpressionMatch match = QRegularExpression("").match(sExcelHtml);
if (!match.hasMatch())
{
throw QString("The excel file format is error.");
}
sTableHtml = match.captured();
sTableHtml.replace(QRegularExpression("\\bx:[^ <>]+\\b"), "");//remove 'x:str' or 'x:num', 'x:...'.
sTableHtml.replace(QRegularExpression(" ]*/>"), "");//remove ''.
sTableHtml.replace(QRegularExpression("]*\\]>[\\S\\s]*"), "");//remove '...'.
HQ_Base::f_Pointer_SetValue(sErr, QString());
return true;
}
catch (QString sExceptionMsg)
{
HQ_Base::f_Pointer_SetValue(sErr, sExceptionMsg);
return false;
}
}
/**================================================================================================
** Import the excel data to the xml string, and output into the parameter 'sXML'.
**===============================================================================================*/
bool HQ_Base_DB_Grid_Excel::f_GetFromExcel_AsXML(QString &sXML, QString *sErr)
{
try
{
sXML.clear();
//Import the excel data into the variable 'sTableHtml' as html.
QString sTableHtml;
if (!f_Excel_GetDataAsHtml(sTableHtml, sErr))
{
return false;
}
QDomDocument doc;
QString sErrMsg;
int iRow, iCol;
if (!doc.setContent(sTableHtml, &sErrMsg, &iRow, &iCol))
{
throw sErrMsg + ", the position in excel file is: row = " + QString::number(iRow)
+ ", col = " + QString::number(iCol) + ".";
}
//Get '', and remove the nodes that is not ' '.
QDomNode node_Table = doc.firstChild();
int i = 0;
while (i < node_Table.childNodes().size())
{
QDomNode node = node_Table.childNodes().at(i);
if (node.nodeName() == "tr")
{
++i;
}
else
{
node_Table.removeChild(node);
}
}
doc.replaceChild(node_Table, doc.firstChild());
sXML = doc.toString();
HQ_Base::f_Pointer_SetValue(sErr, QString());
return true;
}
catch (QString sExceptionMsg)
{
HQ_Base::f_Pointer_SetValue(sErr, sExceptionMsg);
return false;
}
}
/**================================================================================================
** Import the data from the excel file to the json array by the given model.
**===============================================================================================*/
bool HQ_Base_DB_Grid_Excel::f_GetFromExcel(const QString &sModel, QJsonArray &oArrRows, const bool &bFirstRowIsHeader, QString *sErr)
{
try
{
oArrRows = QJsonArray();
//Import the excel data into the variable 'sXML' as the xml string.
QString sXML;
if (!f_GetFromExcel_AsXML(sXML, sErr))
{
return false;
}
QDomDocument doc;
QString sErrMsg;
int iRow, iCol;
if (!doc.setContent(sXML, &sErrMsg, &iRow, &iCol))
{
throw sErrMsg + ", the position in excel file is: row = " + QString::number(iRow)
+ ", col = " + QString::number(iCol) + ".";
}
QDomNode node_Table = doc.firstChild();
//Get the cols info from the model.
QJsonObject oJsonModel = HQ_Base::f_Json_StringToJsonObj(sModel);
if (oJsonModel.isEmpty())
{
throw QString("The given model string can not convert to json object.");
}
QStringList sColList = oJsonModel.value("Cols_Visible").toString().split("|", QString::SkipEmptyParts);
//If it has the header, remove the first node.
if (bFirstRowIsHeader)
{
node_Table.removeChild(node_Table.firstChild());
}
//tr (rows)
int iTrCount = node_Table.childNodes().size();
for (int i_tr = 0; i_tr < iTrCount; ++i_tr)
{
QDomNode node_tr = node_Table.childNodes().at(i_tr);
QJsonObject oJsonRow;
//td (cells)
for (int iCol = 0; iCol < sColList.size(); ++iCol)
{
QString sColName = sColList.at(iCol);
QString sValue;
if (iCol < node_tr.childNodes().size())
{
QDomElement el_td = node_tr.childNodes().at(iCol).toElement();
sValue = el_td.text();
}
oJsonRow.insert(sColName, sValue);
}
oArrRows.append(oJsonRow);
}
HQ_Base::f_Pointer_SetValue(sErr, QString());
return true;
}
catch (QString sExceptionMsg)
{
HQ_Base::f_Pointer_SetValue(sErr, sExceptionMsg);
return false;
}
}
/**================================================================================================
** Import the data from the excel file to the grid.
**===============================================================================================*/
bool HQ_Base_DB_Grid_Excel::f_GetFromExcel(QTableWidget *oGrid, const bool &bFirstRowIsHeader, QString *sErr)
{
try
{
//Import the excel data into the variable 'sXML' as the xml string.
QString sXML;
if (!f_GetFromExcel_AsXML(sXML, sErr))
{
return false;
}
QDomDocument doc;
QString sErrMsg;
int iRow, iCol;
if (!doc.setContent(sXML, &sErrMsg, &iRow, &iCol))
{
throw sErrMsg + ", the position in excel file is: row = " + QString::number(iRow)
+ ", col = " + QString::number(iCol) + ".";
}
QDomNode node_Table = doc.firstChild();
//tr
int iTrCount = node_Table.childNodes().size();
int iRowCount = bFirstRowIsHeader ? iTrCount - 1 : iTrCount;
oGrid->setRowCount(iRowCount);
for (int i_tr = 0; i_tr < iTrCount; ++i_tr)
{
QDomNode node_tr = node_Table.childNodes().at(i_tr);
//td
if (oGrid->columnCount() < node_tr.childNodes().size())
{
oGrid->setColumnCount(node_tr.childNodes().size());
}
for (int i_td = 0; i_td < node_tr.childNodes().size(); ++i_td)
{
QDomElement el_td = node_tr.childNodes().at(i_td).toElement();
QTableWidgetItem *item = new QTableWidgetItem(el_td.text());
if (bFirstRowIsHeader)
{
if (i_tr == 0)
{
oGrid->setHorizontalHeaderItem(i_td, item);
}
else
{
oGrid->setItem(i_tr - 1, i_td, item);
}
}
else
{
oGrid->setItem(i_tr, i_td, item);
}
}
}
HQ_Base::f_Pointer_SetValue(sErr, QString());
return true;
}
catch (QString sExceptionMsg)
{
HQ_Base::f_Pointer_SetValue(sErr, sExceptionMsg);
return false;
}
}
bool HQ_Base_DB_Grid_Excel::f_SetFirstRowToHeader(QTableWidget *oGrid, const bool &bSetHeader, QString *sErr)
{
try
{
//made header
if (bSetHeader)
{
if (oGrid->rowCount() < 1)
{
throw QString("Operation canceled. For the grid row count is lesser than 1.");
}
for (int iCol = 0; iCol < oGrid->columnCount(); ++iCol)
{
QTableWidgetItem *item = oGrid->horizontalHeaderItem(iCol);
if (nullptr == item)
{
item = new QTableWidgetItem;
}
QString sFirstRowCellText;
if (nullptr != oGrid->item(0, iCol))
{
sFirstRowCellText = oGrid->item(0, iCol)->text();
}
item->setText(sFirstRowCellText);
oGrid->setHorizontalHeaderItem(iCol, item);
delete oGrid->item(0, iCol);
}
oGrid->removeRow(0);
}
//remove header
else
{
oGrid->insertRow(0);
for (int iCol = 0; iCol < oGrid->columnCount(); ++iCol)
{
QTableWidgetItem *item = oGrid->horizontalHeaderItem(iCol);
if (nullptr == item)
{
item = new QTableWidgetItem;
}
QString sText = item->text();
item->setText(QString::number(iCol));
oGrid->setHorizontalHeaderItem(iCol, item);
item = new QTableWidgetItem(sText);
oGrid->setItem(0, iCol, item);
}
}
HQ_Base::f_Pointer_SetValue(sErr, QString());
return true;
}
catch (QString sExceptionMsg)
{
HQ_Base::f_Pointer_SetValue(sErr, sExceptionMsg);
return false;
}
}
代码是我又改了一版通用的。因为之前我的电子表格QTabWidget是自己包装过的,可以根据json模板自动加载表头和数据,并处理对齐,用起来更方便。
而我想把excel功能改得让它更通用,不依赖于我包装了类库。其它就没什么了。下面是我的程序运行情况。
4.运行测试:
首先在界面上添加一个按钮,在它的槽函数中写:
//导出excel:
QString sErr;
if (!HQ_Base_DB_Grid_Excel::f_SaveToExcel(ui->oGridMain, false, true, nullptr, &sErr, "SingleGrid"))
{
if (!sErr.isEmpty())
{
QMessageBox::warning(this, "Exporting failed", sErr, QMessageBox::Ok, QMessageBox::NoButton);
}
}
/* 这里oGridMain是我自己命名的,就是一个QTableWidget。
* 后面参数作用:执行前不询问,执行后询问是否要打开exce文件,
* excel文件路径传入nullptr不获取到外部程序,sheet1表单显示名称设置为“SingleGrid”。
*/
//导入excel:
QString sErr;
QString sModel = ui->oGridMain->f_GetModel(&sErr);
QJsonArray oArrRows;
if (!HQ_Base_DB_Grid_Excel::f_GetFromExcel(sModel, oArrRows, false, &sErr))
{
if (!sErr.isEmpty())
{
QMessageBox::warning(this, "Importing failed", sErr, QMessageBox::Ok, QMessageBox::NoButton);
}
return;
}
ui->oGridMain->addRow(oArrRows);
/* 这里oGridMain是用了我自己做的一个表格类。可以自动根据模板加载表头和数据。
* 如果读者想直接用通用的QTableWidget,可以挑选f_GetFromExcel的其它重载。
*/
很简单,主要就调用f_GetFromExcel函数这一行。然后效果就出来了。
代码中又尝试做了excel导入功能,道理类似。就不再贴图了。当然要注意,这种方式既然是基于文本替换实现的,那导入时对文件也有要求,把excel另存为html,或者粘贴到一个html格式的excel文件中。这样才可以被代码解析。
这里我做了取舍,不想依赖office或wps环境,导入时就多了这一步。除非像开发一个wps一样,能够彻底独立操作excel。
上述方法仅仅是一个思路。网上axobject和openxml的方式都有代码,就是不喜欢ax模式,openxml的代码,qt在处理zip时用到了私有库,想去掉警告还挺麻烦的。因为我想实现一个真正没有任何强依赖,又好用的东西。当然目前我做的还差得远。
5.总结:
开头说过,这种方法不完美,但不仅仅是因为上述原因。亲测,wps支持较好,office不行,毕竟这种方法太粗暴。网上看过openxml相关代码,貌似都在vs环境下使用。目前还没想到更好方法,也不想浪费过多时间。
各位高手可以讨论一下,如果有更好的方式,记得交流一下。
本文完。
你可能感兴趣的:(qt/c++,excel,qt,c++)
Ubuntu 安装 OpenCV (C++)
LegendBIT
程序开发--基本工具 ubuntu opencv c++
版本详情:Ubuntu:22.04+5.15.0-133-genericgcc:11.4.0g++:11.4.0OpenCV:4.7.01.卸载OpenCV进入原先编译opencv的build目录,在该目录下打开终端,执行以下代码(如果build已经删除了,可以重新编译一遍该版本的opencv,然后在最后一步执行sudomakeuninstall)sudomakeuninstallcd..sudo
模型/视图编程
潦潦
Qt qt 开发语言
1.MVC包含模型(Model表示数据)、视图(View用户界面)、控制器(Controller界面对用户输入的反应方式)三部分,Qt中还引入了委托(Delegate,又称代理)来对用户输入进行灵活处理,使用它可以定制数据的渲染和编辑方式。QAbstractItemModel是模型的抽象基类TheQAbstractItemModelclassprovidestheabstractinterface
Qt - MVC模型/视图编程
骆驼胡杨
Qt qt
MVC模型/视图编程Qt中的模型/视图架构用来实现大量的数据存储、处理及显示。MVC(Model-View-Controller)包括了3个组件:模型(Model)是应用对象,用来表示数据;视图(View)是模型的用户界面,用来显示数据;控制(Controller)定义了用户界面对用户输入的反应方式。委托(Delegate)用于定制数据的渲染和编辑方式。1.模型所有的模型都基于QAbstractI
QtCreator 模块/视图编程( 一) 模型类,自定义模型QStringListModel,QStandardItemModel,QFileSystemModel,QSqlQueryModel,
psujtfc
Qt QtCreator QtCreator 模块视图 模型类 自定义模型
1模型/视图架构1.1模型所有的模型都是基于QAbstractItemModel类,这个类定义了一个接口,可以供视图和委托来访问数据。Qt提供的现成模型:QStringListModel:用来存储一个简单的QString项目列表QStandardItemModel:管理复杂的树型结构数据项,每一个数据项可以包含任意数据QFileSystemModel:提供了本地文件系统中文件和目录的信息QSqlQ
Qt模型/视图结构
十年编程老舅
QT开发 qt qt开发 Qt模型 qt教程 C++
MVC设计模式是起源于Smalltalk的一种与用户界面相关的设计模式。通过使用此模式,可以有效地分离数据和用户界面。MVC设计模式包括三个元素:表示数据的模型(Model)、表示用户界面的视图(View)和定义了用户在界面上操作的控制器(Controller)。与MVC设计模式类似,Qt引入了模型/视图结构用于完成数据与界面的分离,即InterView框架。但不同的是,Qt的InterView框
线程池代码分析及延申应用
埃菲尔铁塔_CV算法
c++ 算法 开发语言 人工智能 opencv 机器学习
代码功能概述这段C++代码实现了一个简单的线程池类MthreadPool,线程池是一种用于管理和复用线程的机制,它可以避免频繁创建和销毁线程带来的开销,提高程序的性能。MthreadPool类允许用户指定线程池的最小和最大线程数,并提供了添加任务、管理线程数量等功能。代码详细解释1.类的定义和成员变量#include"MthreadPool.h"MthreadPool::MthreadPool(i
C++ List
练气十三层
STL c++
C++11中的std::list是一种双向链表容器。在底层,std::list的每个元素都被包装在一个节点内,每个节点包括一个指向前一个节点的指针、一个指向后一个节点的指针以及元素本身。下面是std::list常用的功能及示例:插入元素#include#includeintmain(){std::listmylist={1,2,3};//在头部插入元素mylist.push_front(0);//
探索Node.js的原生插件新境界:使用`node-gyp`
洪新龙
探索Node.js的原生插件新境界:使用node-gypnode-gypNode.jsnativeaddonbuildtool项目地址:https://gitcode.com/gh_mirrors/no/node-gyp在Node.js的生态系统中,将高性能的C/C++代码融入到JavaScript世界已经成为提升应用性能的关键手段。今天,我们要向大家隆重推荐一个不可或缺的工具——node-gyp
C++ list:链表的“乐高积木”与“灵活小火车”
福鸦
c++ c++ list 链表
C++list:链表的“乐高积木”与“灵活小火车”开篇小故事:魔术师的“无限链条”想象一位魔术师有一条神奇的链条:他可以瞬间在任意位置插入或取下链环,无需打断整条链条。每个链环都自带“记忆”,能记住前后邻居的位置。链条可以无限延长或缩短,且永远保持连贯。这就是C++标准库中的**list**——它用双向链表的结构,赋予你高效增删元素的能力,告别数组搬移数据的笨重操作!一、list是什么?std::
QT5在windows下调用OpenCV库出现: undefined reference to `xxxxx' 错误解决办法(适用MinGW编译器)。
DS小龙哥
QT(C++)应用软件开发 AI人工智能 opencv
一、环境介绍window系统:win10X64QT版本:5.12QT5.12自带的MinGW编译器版本:mingw730_32与mingw730_64在QT的安装目录下,可以查看MinGW编译器的版本:二、使用OpenCV出现的问题在QT框架代码里使用老版本的分类器(cvLoad、cvHaarDetectObjects)处理图像时,正常编译没有问题,当使用新版本级联分类器(CascadeClass
C++/Qt 信号槽机制详解
_S_Q
Qt Qt开发 c++ qt
文章目录C++/Qt信号槽机制详解一、信号和槽的基本概念1.信号2.槽3.连接二、信号和槽的基本使用1.信号和槽的声明和定义2.连接信号和槽三、信号和槽的工作原理1.MOC(Meta-ObjectCompiler)2.事件循环3.连接类型四、信号和槽的高级应用1.自定义信号和槽2.Lambda表达式和函数对象3.信号和槽的断开连接五、总结C++/Qt信号槽机制详解信号和槽是Qt框架中用于对象间通信
Qt反射机制与信号槽机制
百口可乐__
Qt- qt 开发语言 c++
反射机制介绍:Qt反射机制是基于moc(metaobjectcompiler)实现的moc全称是Meta-ObjectCompiler,也就是“元对象编译器”。Qt程序在交由标准编译器编译之前,先要使用moc分析C++源文件。如果它发现在一个头文件中包含了宏Q_OBJECT,则会生成另外一个C++源文件。这个源文件中包含了Q_OBJECT宏的实现代码。这个新的文件名字将会是原文件名前面加上moc_
Window on arm编译onnxruntime的python安装包
lpcarl
Windows on arm开发 python WOA Windows on arm onnx
Windowonarm编译onnxruntime_qnn的python安装包准备工作开始安装准备工作1.下载onnxruntime的源码gitclonehttps://github.com/microsoft/onnxruntime.git2.安装vsstudio下载visualstudio安装包,并在线安装visualstudio2022版本,安装完成后安装“c++桌面应用开发”相关的组件下载c
2024年03月 C/C++(七级)真题解析#中国电子学会#全国青少年软件编程等级考试
码农StayUp
# C/C++七八级历届真题解析 c语言 c++ 开发语言 电子学会 等级考试
C/C++编程(1~8级)全部真题・点这里第1题:走出迷宫当你站在一个迷宫里的时候,往往会被错综复杂的道路弄得失去方向感,如果你能得到迷宫地图,事情就会变得非常简单。假设你已经得到了一个n*m的迷宫的图纸,请你找出从起点到出口的最短路。时间限制:1000内存限制:65536输入第一行是两个整数n和m(1<=n,m<=100),表示迷宫的行数和列数。接下来n行,每行一个长为m的字符串,表示整个迷宫的
C++内存操纵的十二维解构艺术
王强你强
编程技术 c++ java 开发语言
在C++的混沌宇宙中,指针是打开时空裂缝的密钥。本文将以全新视角解构指针的本质,揭示从堆栈穿梭到多维空间映射的进阶技法,展示现代C++赋予指针的惊人可能性。一、指针本体论:内存的波粒二象性所有指针变量都是量子化的存在,既指向具体内存位置,又携带类型信息波。通过类型系统实验可验证其双重属性:templatevoidquantum_observer(T*ptr){std::cout(ptr)(&c)v
Open3D(C++) 可视化(1)——绘制平面模型
点云侠
Open3D学习 c++ 平面 开发语言 算法 3d
目录一、概述二、代码实现三、结果展示一、概述 Open3D中没有实现绘制平面的功能,故自己写代码进行实现。效果如下:二、代码实现#include#include//生成平面模型staticstd
Open3D(C++) 可视化绘制平面模型
后端架构魔术师
c++ 平面 开发语言 编程
Open3D(C++)可视化绘制平面模型Open3D是一个现代化的3D图像处理引擎,它包含很多常用的3D操作,如点云分割、重构、配准等。其中,在可视化方面Open3D也提供了一系列方便易用的函数和接口。在本篇文章中,我们将介绍如何使用Open3D绘制一个简单的平面模型并进行可视化展示。下面是完整的源代码:#include#includeintmain(){//创建平面顶点std::vectorve
关于vs一个项目提示main被多次引用的解决方法
_DT9825
c++ 开发语言 visual studio ide
错误信息如图首先,在VisualStudio中遇到“多个main函数被引用”的报错,通常是因为同一个项目中存在多个包含main函数(程序入口点)的源文件。原因这是由于C/C++程序的入口规则,每个可执行程序(如.exe)必须且只能有一个入口点(即main函数)。如果项目中多个文件定义了main函数,编译器在链接阶段会因冲突而报错。第二个就是项目结构问题,VisualStudio默认将同一项目下的所
【花雕学编程】ESP32 DeepSeek 之带样式的Web聊天机器人
驴友花雕
开源硬件 机器人 嵌入式硬件 单片机 c++ 带样式的Web聊天机器人 ESP32 DeepSeek
Arduino是一个开放源码的电子原型平台,它可以让你用简单的硬件和软件来创建各种互动的项目。Arduino的核心是一个微控制器板,它可以通过一系列的引脚来连接各种传感器、执行器、显示器等外部设备。Arduino的编程是基于C/C++语言的,你可以使用ArduinoIDE(集成开发环境)来编写、编译和上传代码到Arduino板上。Arduino还有一个丰富的库和社区,你可以利用它们来扩展Ardui
【花雕学编程】Arduino JSON 之跨平台兼容性
驴友花雕
开源硬件 json 嵌入式硬件 单片机 c++ 跨平台兼容性 Arduino JSON
Arduino是一个开放源码的电子原型平台,它可以让你用简单的硬件和软件来创建各种互动的项目。Arduino的核心是一个微控制器板,它可以通过一系列的引脚来连接各种传感器、执行器、显示器等外部设备。Arduino的编程是基于C/C++语言的,你可以使用ArduinoIDE(集成开发环境)来编写、编译和上传代码到Arduino板上。Arduino还有一个丰富的库和社区,你可以利用它们来扩展Ardui
【花雕学编程】Arduino RTOS 之高效多线程并发操作
驴友花雕
mfc c++ 驱动开发 嵌入式硬件 单片机 高效多线程并发操作 Arduino RTOS
Arduino是一个开放源码的电子原型平台,它可以让你用简单的硬件和软件来创建各种互动的项目。Arduino的核心是一个微控制器板,它可以通过一系列的引脚来连接各种传感器、执行器、显示器等外部设备。Arduino的编程是基于C/C++语言的,你可以使用ArduinoIDE(集成开发环境)来编写、编译和上传代码到Arduino板上。Arduino还有一个丰富的库和社区,你可以利用它们来扩展Ardui
【花雕学编程】Arduino FOC 之 Arduino SCARA机器人
驴友花雕
机器人 嵌入式硬件 单片机 c++ SCARA机器人 Arduino FOC
Arduino是一个开放源码的电子原型平台,它可以让你用简单的硬件和软件来创建各种互动的项目。Arduino的核心是一个微控制器板,它可以通过一系列的引脚来连接各种传感器、执行器、显示器等外部设备。Arduino的编程是基于C/C++语言的,你可以使用ArduinoIDE(集成开发环境)来编写、编译和上传代码到Arduino板上。Arduino还有一个丰富的库和社区,你可以利用它们来扩展Ardui
【花雕学编程】Arduino CNC
驴友花雕
嵌入式硬件 单片机 Arduino CNC
Arduino是一个开放源码的电子原型平台,它可以让你用简单的硬件和软件来创建各种互动的项目。Arduino的核心是一个微控制器板,它可以通过一系列的引脚来连接各种传感器、执行器、显示器等外部设备。Arduino的编程是基于C/C++语言的,你可以使用ArduinoIDE(集成开发环境)来编写、编译和上传代码到Arduino板上。Arduino还有一个丰富的库和社区,你可以利用它们来扩展Ardui
【花雕学编程】Arduino BLDC 之智能平衡车
驴友花雕
Arduino BLDC 嵌入式硬件 单片机 c++ Arduino BLDC 智能平衡车 智能化控制
Arduino是一个开放源码的电子原型平台,它可以让你用简单的硬件和软件来创建各种互动的项目。Arduino的核心是一个微控制器板,它可以通过一系列的引脚来连接各种传感器、执行器、显示器等外部设备。Arduino的编程是基于C/C++语言的,你可以使用ArduinoIDE(集成开发环境)来编写、编译和上传代码到Arduino板上。Arduino还有一个丰富的库和社区,你可以利用它们来扩展Ardui
java 反射创建对象作用_java反射机制(原理/应用场景/创建对象)详解
文艺范理工生
java 反射创建对象作用
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。JAVA反射(放射)机制:“程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。但是JAVA有
bug 系列 expected <class ‘openpyxl.styles.fills.Fill‘>
SHolmes1854
python
expectedpandas这个读取excel是为啥改用openxyl也不行,最后,看别人说的,把这个文档另存为居然就可以了…然后我发现居然真的可以
C#加班统计次数
回家的诱惑
C# c# 开发语言
C#加班统计次数运行环境:vs2022.net8.0社区版1、用C#语言;2、有界面上传Excel文件;3、对Excel列(部门、人员姓名、人员编号、考勤时间)处理:(1)按人员编号、考勤日期分组且保留原来字段,保留唯一最晚考勤时间记录,(2)按人员编号分组,统计分组员工加班次数:判断条件(1)周一至周五(2)打卡时间超过17:304、输出Excel在另一个sheet标签统计。usingSyste
【信息学奥赛一本通 C++题解】1286:怪盗基德的滑翔翼
信奥大黄
信息学奥赛一本通 c++ 算法
信息学奥赛一本通(C++版)在线评测系统基础算法第一节动态规划的基本模型1286:怪盗基德的滑翔翼1.理解题意同学们,我们一起来看怪盗基德遇到的这个有趣问题哦。怪盗基德成功偷到了钻石,可倒霉的是他的滑翔翼动力装置被柯南破坏了。现在他在一个城市里,这个城市有一排建筑,一共有N幢,而且每幢建筑的高度都不一样呢。基德可以从这一排建筑中的任意一幢的顶部开始他的逃跑旅程哦。不过他有两个限制条件:一是他只能朝
C++调用CPLEX踩过的小坑~
blackms1023
c++
最近在使用VisualStudio2015调用CPLEX进行一些基础问题的求解,初学小白,完全没经验,遇到N多问题,踩了好多坑,在此分享一下!希望可以给后其他研究者提供一neinei学习的经验!1.关于CPLEX中默认变量的问题CPLEX中默认变量为非负值,故在实际编码过程中如若不为变量指定下界为负无穷,且变量存在负值情况,则会出现计算数据错误的情况。具体解决方法就是在初始化的过程中,为其指定一个
学C++还是学Java?做软件研发还需掌握哪些知识和技能?_c+
2401_84160087
程序员 c++ java c语言
1.1、Java和C++都很有前途1.2、Java的应用领域与使用场景1.3、C++的应用领域与使用场景1.4、如何选择2、需要掌握的知识和技能2.1、掌握一些基础的网络知识2.2、熟悉一些常用的SQL语句2.3、了解Linux系统,掌握常用的Linux命令2.4、学习汇编语言相关的内容2.5、学习一些其他的专业课程3、最后最近和一些高校的学生朋友交流,他们打算毕业后从事软件研发的工作,但目前有些
面向对象面向过程
3213213333332132
java
面向对象:把要完成的一件事,通过对象间的协作实现。
面向过程:把要完成的一件事,通过循序依次调用各个模块实现。
我把大象装进冰箱这件事为例,用面向对象和面向过程实现,都是用java代码完成。
1、面向对象
package bigDemo.ObjectOriented;
/**
* 大象类
*
* @Description
* @author FuJian
Java Hotspot: Remove the Permanent Generation
bookjovi
HotSpot
openjdk上关于hotspot将移除永久带的描述非常详细,http://openjdk.java.net/jeps/122
JEP 122: Remove the Permanent Generation
Author Jon Masamitsu
Organization Oracle
Created 2010/8/15
Updated 2011/
正则表达式向前查找向后查找,环绕或零宽断言
dcj3sjt126com
正则表达式
向前查找和向后查找
1. 向前查找:根据要匹配的字符序列后面存在一个特定的字符序列(肯定式向前查找)或不存在一个特定的序列(否定式向前查找)来决定是否匹配。.NET将向前查找称之为零宽度向前查找断言。
对于向前查找,出现在指定项之后的字符序列不会被正则表达式引擎返回。
2. 向后查找:一个要匹配的字符序列前面有或者没有指定的
BaseDao
171815164
seda
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class BaseDao {
public Conn
Ant标签详解--Java命令
g21121
Java命令
这一篇主要介绍与java相关标签的使用 终于开始重头戏了,Java部分是我们关注的重点也是项目中用处最多的部分。
1
[简单]代码片段_电梯数字排列
53873039oycg
代码
今天看电梯数字排列是9 18 26这样呈倒N排列的,写了个类似的打印例子,如下:
import java.util.Arrays;
public class 电梯数字排列_S3_Test {
public static void main(S
Hessian原理
云端月影
hessian原理
Hessian 原理分析
一. 远程通讯协议的基本原理
网络通信需要做的就是将流从一台计算机传输到另外一台计算机,基于传输协议和网络 IO 来实现,其中传输协议比较出名的有 http 、 tcp 、 udp 等等, http 、 tcp 、 udp 都是在基于 Socket 概念上为某类应用场景而扩展出的传输协
区分Activity的四种加载模式----以及Intent的setFlags
aijuans
android
在多Activity开发中,有可能是自己应用之间的Activity跳转,或者夹带其他应用的可复用Activity。可能会希望跳转到原来某个Activity实例,而不是产生大量重复的Activity。
这需要为Activity配置特定的加载模式,而不是使用默认的加载模式。 加载模式分类及在哪里配置
Activity有四种加载模式:
standard
singleTop
hibernate几个核心API及其查询分析
antonyup_2006
html .net Hibernate xml 配置管理
(一) org.hibernate.cfg.Configuration类
读取配置文件并创建唯一的SessionFactory对象.(一般,程序初始化hibernate时创建.)
Configuration co
PL/SQL的流程控制
百合不是茶
oracle PL/SQL编程 循环控制
PL/SQL也是一门高级语言,所以流程控制是必须要有的,oracle数据库的pl/sql比sqlserver数据库要难,很多pl/sql中有的sqlserver里面没有
流程控制;
分支语句 if 条件 then 结果 else 结果 end if ;
条件语句 case when 条件 then 结果;
循环语句 loop
强大的Mockito测试框架
bijian1013
mockito 单元测试
一.自动生成Mock类 在需要Mock的属性上标记@Mock注解,然后@RunWith中配置Mockito的TestRunner或者在setUp()方法中显示调用MockitoAnnotations.initMocks(this);生成Mock类即可。二.自动注入Mock类到被测试类 &nbs
精通Oracle10编程SQL(11)开发子程序
bijian1013
oracle 数据库 plsql
/*
*开发子程序
*/
--子程序目是指被命名的PL/SQL块,这种块可以带有参数,可以在不同应用程序中多次调用
--PL/SQL有两种类型的子程序:过程和函数
--开发过程
--建立过程:不带任何参数
CREATE OR REPLACE PROCEDURE out_time
IS
BEGIN
DBMS_OUTPUT.put_line(systimestamp);
E
【EhCache一】EhCache版Hello World
bit1129
Hello world
本篇是EhCache系列的第一篇,总体介绍使用EhCache缓存进行CRUD的API的基本使用,更细节的内容包括EhCache源代码和设计、实现原理在接下来的文章中进行介绍
环境准备
1.新建Maven项目
2.添加EhCache的Maven依赖
<dependency>
<groupId>ne
学习EJB3基础知识笔记
白糖_
bean Hibernate jboss webservice ejb
最近项目进入系统测试阶段,全赖袁大虾领导有力,保持一周零bug记录,这也让自己腾出不少时间补充知识。花了两天时间把“传智播客EJB3.0”看完了,EJB基本的知识也有些了解,在这记录下EJB的部分知识,以供自己以后复习使用。
EJB是sun的服务器端组件模型,最大的用处是部署分布式应用程序。EJB (Enterprise JavaBean)是J2EE的一部分,定义了一个用于开发基
angular.bootstrap
boyitech
AngularJS AngularJS API angular中文api
angular.bootstrap
描述:
手动初始化angular。
这个函数会自动检测创建的module有没有被加载多次,如果有则会在浏览器的控制台打出警告日志,并且不会再次加载。这样可以避免在程序运行过程中许多奇怪的问题发生。
使用方法: angular .
java-谷歌面试题-给定一个固定长度的数组,将递增整数序列写入这个数组。当写到数组尾部时,返回数组开始重新写,并覆盖先前写过的数
bylijinnan
java
public class SearchInShiftedArray {
/**
* 题目:给定一个固定长度的数组,将递增整数序列写入这个数组。当写到数组尾部时,返回数组开始重新写,并覆盖先前写过的数。
* 请在这个特殊数组中找出给定的整数。
* 解答:
* 其实就是“旋转数组”。旋转数组的最小元素见http://bylijinnan.iteye.com/bl
天使还是魔鬼?都是我们制造
ducklsl
生活 教育 情感
----------------------------剧透请原谅,有兴趣的朋友可以自己看看电影,互相讨论哦!!!
从厦门回来的动车上,无意中瞟到了书中推荐的几部关于儿童的电影。当然,这几部电影可能会另大家失望,并不是类似小鬼当家的电影,而是关于“坏小孩”的电影!
自己挑了两部先看了看,但是发现看完之后,心里久久不能平
[机器智能与生物]研究生物智能的问题
comsci
生物
我想,人的神经网络和苍蝇的神经网络,并没有本质的区别...就是大规模拓扑系统和中小规模拓扑分析的区别....
但是,如果去研究活体人类的神经网络和脑系统,可能会受到一些法律和道德方面的限制,而且研究结果也不一定可靠,那么希望从事生物神经网络研究的朋友,不如把
获取Android Device的信息
dai_lm
android
String phoneInfo = "PRODUCT: " + android.os.Build.PRODUCT;
phoneInfo += ", CPU_ABI: " + android.os.Build.CPU_ABI;
phoneInfo += ", TAGS: " + android.os.Build.TAGS;
ph
最佳字符串匹配算法(Damerau-Levenshtein距离算法)的Java实现
datamachine
java 算法 字符串匹配
原文:http://www.javacodegeeks.com/2013/11/java-implementation-of-optimal-string-alignment.html------------------------------------------------------------------------------------------------------------
小学5年级英语单词背诵第一课
dcj3sjt126com
english word
long 长的
show 给...看,出示
mouth 口,嘴
write 写
use 用,使用
take 拿,带来
hand 手
clever 聪明的
often 经常
wash 洗
slow 慢的
house 房子
water 水
clean 清洁的
supper 晚餐
out 在外
face 脸,
macvim的使用实战
dcj3sjt126com
mac vim
macvim用的是mac里面的vim, 只不过是一个GUI的APP, 相当于一个壳
1. 下载macvim
https://code.google.com/p/macvim/
2. 了解macvim
:h vim的使用帮助信息
:h macvim
java二分法查找
蕃薯耀
java二分法查找 二分法 java二分法
java二分法查找
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
蕃薯耀 2015年6月23日 11:40:03 星期二
http:/
Spring Cache注解+Memcached
hanqunfeng
spring memcached
Spring3.1 Cache注解
依赖jar包:
<!-- simple-spring-memcached -->
<dependency>
<groupId>com.google.code.simple-spring-memcached</groupId>
<artifactId>simple-s
apache commons io包快速入门
jackyrong
apache commons
原文参考
http://www.javacodegeeks.com/2014/10/apache-commons-io-tutorial.html
Apache Commons IO 包绝对是好东西,地址在http://commons.apache.org/proper/commons-io/,下面用例子分别介绍:
1) 工具类
2
如何学习编程
lampcy
java 编程 C++ c
首先,我想说一下学习思想.学编程其实跟网络游戏有着类似的效果.开始的时候,你会对那些代码,函数等产生很大的兴趣,尤其是刚接触编程的人,刚学习第一种语言的人.可是,当你一步步深入的时候,你会发现你没有了以前那种斗志.就好象你在玩韩国泡菜网游似的,玩到一定程度,每天就是练级练级,完全是一个想冲到高级别的意志力在支持着你.而学编程就更难了,学了两个月后,总是觉得你好象全都学会了,却又什么都做不了,又没有
架构师之spring-----spring3.0新特性的bean加载控制@DependsOn和@Lazy
nannan408
Spring3
1.前言。
如题。
2.描述。
@DependsOn用于强制初始化其他Bean。可以修饰Bean类或方法,使用该Annotation时可以指定一个字符串数组作为参数,每个数组元素对应于一个强制初始化的Bean。
@DependsOn({"steelAxe","abc"})
@Comp
Spring4+quartz2的配置和代码方式调度
Everyday都不同
代码 配置 spring4 quartz2.x 定时任务
前言:这些天简直被quartz虐哭。。因为quartz 2.x版本相比quartz1.x版本的API改动太多,所以,只好自己去查阅底层API……
quartz定时任务必须搞清楚几个概念:
JobDetail——处理类
Trigger——触发器,指定触发时间,必须要有JobDetail属性,即触发对象
Scheduler——调度器,组织处理类和触发器,配置方式一般只需指定触发
Hibernate入门
tntxia
Hibernate
前言
使用面向对象的语言和关系型的数据库,开发起来很繁琐,费时。由于现在流行的数据库都不面向对象。Hibernate 是一个Java的ORM(Object/Relational Mapping)解决方案。
Hibernte不仅关心把Java对象对应到数据库的表中,而且提供了请求和检索的方法。简化了手工进行JDBC操作的流程。
如
Math类
xiaoxing598
Math
一、Java中的数字(Math)类是final类,不可继承。
1、常数 PI:double圆周率 E:double自然对数
2、截取(注意方法的返回类型) double ceil(double d) 返回不小于d的最小整数 double floor(double d) 返回不大于d的整最大数 int round(float f) 返回四舍五入后的整数 long round