Qt - 外部子模块的3种使用方法,以QtXlsx为例
概述
Qt版本升级过程中会新增某些功能模块并打包到安装包中,同时官方会以子模块的形式发布其源码,
如果要在旧版本开发的项目中使用,有以下3种方式(重点讲第2种方式)。
注:
1、两种使用子模块的方式都需要安装perl语言执行环境(Linux平台自带),可使用 perl -v 查看是否已安装
2、在安装Qt时就可以勾选安装 Strawberry Perl 模块,如果没有安装的按照下面提示单独安装一下
3、Perl 在 Window 平台上有 ActiveStatePerl 和 Strawberry Perl 两种编译器
4、选 Strawberry Perl 更方便,根据Qt编译器32/64bit版本下载对应版本,地址:http://strawberryperl.com
先介绍一下:Qt安装目录(以Qt5.9版本为例)
如上图所示,添加的子模块都会放在QTDIR(Qt类库文件夹)中,其中子模块关注的目录:
- bin:用于存放Qt的运行库,我们将子模块编译生成的.dll文件拷贝到该目录下;
- include:用于存放头文件,我们将子模块的头文件拷贝到该目录下;
- lib:用于存放静态库文件,我们将子模块编译生成的.a(mingw编译器)或.lib(msvc编译器)文件拷贝到该目录下;
- mkspecs:该目录下有个modules文件夹,我们将子模块编译生成.pri文件拷贝到该目录下。
方式1:直接在项目中使用子模块源码
1、将源码放在项目目录下
|-- project.pro |-- .... |-- 3rdparty\ | |-- qtxlsx\ | |
2、在项目pro文件中添加
include(3rdparty/qtxlsx/src/xlsx/qtxlsx.pri)
3、在mian.cpp中添加头文件即可
#include "xlsxdocument.h" int main(){ QXlsx::Document xlsx; xlsx.write("A1", "Hello Qt!"); xlsx.saveAs("Test.xlsx"); return 0; }
方式2:编译子模块源码并将其添加为Qt的子模块(以QtXlsx为例)
我们只需要下载这个子模块的源码进行编译并安装到开发环境中即可。
1、下载子模块源码
博主使用的是旧版本的QtXlsx,已经很久没有维护了,推荐大家使用目前正在维护的新版本
源码地址(旧):https://github.com/dbzhang800/QtXlsxWriter
源码地址(新):https://github.com/QtExcel/QXlsx(这个版本不需要perl环境,待验证)
API使用文档地址: http://qtxlsx.debao.me
2、编译子模块源码
用Qt Create打开源码目录下pro文件,在项目配置界面做一下配置:
选择编译套件kits,如果像博主一样使用VS+Qt开发环境就选择MSVC(用Qt开发环境就选择MinGw)
构建步骤中默认选择使用qmake(也可选使用make,需要加宏,不推荐)
开始构建编译
完成后在编译目录生成三个文件夹,include、lib、mkspecs(模块pri)
include:子模块头文件
lib:子模块库文件,包含静态链接库和动态链接库
mkspecs:子模块pri文件
3、添加为Qt子模块(安装子模块)
将生成的include文件夹下的QtXlsx文件夹拷贝到msvc\include下(注意看头文件内容是否为头文件的相对路径,是则需要替换为包含内容的头文件)
将生成的lib文件夹下Qt5Xlsxd.lib、Qt5Xlsx.lib、Qt5Xlsx.prl、Qt5Xlsxd.prl拷贝到msvc\lib下
将生成的lib下Qt5Xlsx.dll、Qt5Xlsxd.dll拷贝到msvc\bin下
将生成的mkspecs\modules-inst下qt_lib_xlsx.pri、qt_lib_xlsx_private.pri拷贝到msvc\mkspecs\modules下(此步不做则pro文件中添加QT += xlsx模块不会被识别)
4、测试子模块
新建Qt项目,在pro文件中添加QT += xlsx
如果是VS+Qt环境,则右键项目->属性->Qt Project Settings手动添加xlsx
#include <QtXlsx/xlsxdocument.h> int main(){ QXlsx::Document xlsx; xlsx.write("A1", "Hello Qt!"); xlsx.saveAs("test.xlsx"); return 0; }
构建项目后会生成test.xlsx文件,打开文件内容如下即成功
方式3:使用方式2编译的头文件和库文件,当作动态库使用,不添加到Qt子模块中
QtXlsx使用
QtXlsx官方示例使用:https://tangxing.blog.csdn.net/article/details/111769792
附上QtXlsx常用API使用方式:
1 //xlsx操作单元格 2 xlsx.mergeCells("A1:Q1"); 3 xlsx.setColumnWidth(1,15) 4 xlsx.setRowHeight(1,4,30) 5 //xlsx跳转指定的sheet 6 xlsx.selectSheet("sheetName"); 7 //xlsx获取当前表的行数、列数 8 xlsx.dimension().rowCount(); 9 xlsx.dimension().columnCount(); 10 //xlsx查看文件中所有表名 11 xlsx.sheetNames() 12 //xlsx增加一个表 13 xlsx.addSheet() 14 //xlsx的cell格式化 15 Format cellFormat; 16 cellFormat.setFontSize(11); 17 cellFormat.setFontColor(QColor(Qt::black)); 18 cellFormat.setBorderStyle(Format::BorderThin); 19 cellFormat.setHorizontalAlignment(Format::AlignHCenter); 20 cellFormat.setVerticalAlignment(Format::AlignVCenter); 21 //xlsx写入表格显示中文乱码 22 QString::fromLocal8Bit("亮度均匀性(Luminance Uniformity)") 23 //QStringList中查找到某一个字符串的索引位置(找不到返回-1) 24 QStringList的indexOf() 25 //tableWidget里面的item是空的时候程序会中断 26 因为当item是空的时候, 27 ui->tableWidget->item(now_row,now_column); 28 得到的是一个空指针所以不能用text()去获取文本!
1 //写入 2 QXlsx::Document xlsx; 3 if(!xlsx.selectSheet("ziv"))//选择表格,若不存在,则新建一张 4 { 5 xlsx.addSheet("ziv"); 6 } 7 xlsx.write("A1", "View the properties through:"); 8 xlsx.write("A2", "Office Button -> Prepare -> Properties option in Excel"); 9 if(!xlsx.selectSheet("agv")) 10 { 11 xlsx.addSheet("agv"); 12 } 13 xlsx.write("A1","ip"); 14 xlsx.write("A2","192.168"); 15 xlsx.saveAs("book1.xlsx"); //添加后,必须保存至表格中 16 QXlsx::CellRange range;//获取表格的行数、列数 17 range=xlsx.dimension(); 18 int rowCount = range.rowCount() ; //行数 19 int colCount = range.columnCount() ; //列数 20 //更新某一行 21 for(int i=1; i<rowCount+1; i++) 22 { 23 if ( xlsx.cellAt( i ,1)->value().toString()=="192.168" ) 24 { 25 xlsx.write(i,1,"192.168.31"); 26 } 27 } 28 xlsx.saveAs("book1.xlsx");//更新后一定要保存 29 xlsx1.selectSheet("agv"); 30 //读取agv表中的所有信息 31 for (int i = 1; i <=rowCount; i++) 32 { 33 for (int j=1; j<=colCount; j++) 34 { 35 qDebug() << i <<j <<xlsx1.cellAt(i, j)->value().toString() ; 36 } 37 } 38 qDebug() << rowCountt <<colCountt <<xlsx1.currentSheet()->sheetName();//打印出表单的名字 39 40 bool flag= xlsx.deleteSheet("agv");//删除某一表,删除后必须保存 41 if(flag) 42 { 43 qDebug() <<"true" ; 44 } 45 else 46 { 47 qDebug() <<"false" ; 48 } 49 xlsx.saveAs("book1.xlsx"); 50 xlsx.copySheet("ziv","chen");//无格式拷贝 51 xlsx.selectSheet("chen"); 52 xlsx.write(4,2,"On the Copy Sheet"); 53 xlsx.saveAs("book1.xlsx"); 54 55 56 57 //读取 58 QXlsx::Document xlsx1("book1.xlsx"); 59 xlsx1.selectSheet("ziv"); 60 QStringList sheetname_tmp = xlsx1.sheetNames();//表单名 61 qDebug() << "表单名" <<sheetname_tmp; 62 QString tmp = sheetname_tmp.join(","); 63 qDebug() <<"tmp" << tmp; 64 xlsx1.selectSheet("ziv"); 65 qDebug()<<xlsx1.read("A1").toString()<<xlsx1.read("A2").toInt()<<xlsx1.read("A3").toBool(); 66 67 //若想判断单元格是不是空白 68 QString filepath= "D:/LgvResource/dxfInfo.xlsx" ; 69 QXlsx::Document xlsx(filepath);//读取excel 70 //选择表SiteInfo //ID、posX、posY、nature、startx、starty width height 71 if(!xlsx.selectSheet("SiteInfo")) 72 { 73 qDebug()<<"表格不存在"+filepath + "SiteInfo"; 74 return; 75 } 76 QXlsx::Cell *cell = xlsx.cellAt(2,1); 77 if(cell == NULL) 78 { 79 qDebug()<<"null"; 80 } 81 else { 82 qDebug()<<cell->value().toString(); 83 }