QGIS库QgsRasterLayer的构造函数警告
应用程序输出Empty filename passed to function有的还会伴随着proj_create_from_wkt: Cannot find proj.db和proj_create_from_database: Cannot find proj.db的报错
(省流:直接看最后的总结)
这是我的源代码,如下:
QString pathName = "images/ahs.mbtiles";//相对路径
QStringList temp = pathName.split('/');
QString basename = temp.at(temp.size() - 1);
qDebug() << "打印瓦片图的路径:" << pathName;
//有Empty filename passed to function报错,依然可以用
QgsRasterLayer* rasterLayer = new QgsRasterLayer(pathName, basename);
if (!rasterLayer->isValid())
{
QMessageBox::critical(this, "error", QString("layer is invalid: \n") + pathName);
return;
}
结果路径存在,QMessageBox的提示框没有弹出来,说明rasterLayer->isValid()为真,路径存在,栅格地图也加载在一个QWidget对象中了。
但是程序输出面板是这样的:
libpng warning: iCCP: known incorrect sRGB profile
libpng warning: iCCP: known incorrect sRGB profile
打印瓦片图的路径 “images/ahs.mbtiles”
Empty filename passed to function
我只能把这句当做是和上面的图片没转成Adobe RGB的配置模式一样。图片这个警告能去了,但是我这QgsRasterLayer类的构造换成绝对路径加载或者在qrc资源里加载还是一样的有一句Empty filename passed to function。不同的项目工程似乎是随机出现的,我用的是QGIS3.16稳定版的库,QGIS源码太多没看到这句,有知道的告知一下。
Empty filename passed to function提示对用windeployqt打包后的exe程序没有影响
没有影响,一开始我把打包好的exe拷贝去了别的电脑,发现功能正常就地图加载不上。以为是Empty filename passed to function这句话带来的异常有影响,后来才知道是新电脑缺一个环境变量。就是这个:
点新建加上这个PROJ_LIB
mbtiles包的加载需要这个变量,Path路径下全是dll动态库,要拷贝去exe同级文件夹。这个PROJ_LIB变量的值是I:\OSGeo4W\share\proj的路径下是OSGeo4W资源包在安装的时候生成的qgis-ltr-bin.env文件中写的,具体的环境变量的值看下面的简单记录两句。
PROJ_LIB变量来源于QGIS二次开发的环境配置
我的在线安装OSGeo4W的资源包就在I盘根目录,在I盘的I:\OSGeo4W\bin\目录中有一个qgis-ltr-bin.exe的程序,如果能打开运行说明qgis-ltr-bin.env文件没问题能用,env中环境变量是随安装的时候写的绝对路径,如果移动走则exe打不开了。(不用稳定版就用qgis-bin.exe和qgis-bin.env文件)
QGIS二次开发配置环境变量
确定qgis-ltr-bin.exe程序能打开运行,然后用记事本打开qgis-ltr-bin.env,再打开自己电脑的环境变量,对照env文件里配置就行了。由于我拷了很多dll动态库在release文件夹下了,所以环境变量就配置Path和PROJ_LIB两个键的值。
总结
Empty filename passed to function提示是QgsRasterLayer类构造随机引出来的,但是不影响程序运行和打包,有时候加载不了地图包是因为配置环境变量的时候少了PROJ_LIB=XXX盘:\OSGeo4W\share\proj引起的,PROJ_LIB的值写啥是取决于下载的OSGeo4W中的一个qgis-ltr-bin.env中写了啥。
打包后拷贝去新电脑无法运行的解决办法,就是各种方式添加环境变量
解决方式一:
手动在新电脑里添加这个PROJ_LIB=X盘:\OSGeo4W\share\proj环境变量。
解决方式二:
Qt添加临时环境变量,写在代码里。
我的缺的环境变量是PROJ_LIB=X盘:\OSGeo4W\share\proj这个环境变量,我把这里的proj文件夹拷贝我的exe可同级目录下了(如果是在QtCreate里运行应该是拷贝到工程文件根目录)
#include <QtGlobal>//头文件
#include <QDir>
int main(int argc, char *argv[])
{
QDir dir;
QString PROJ_LIB_PATH = dir.currentPath() + "/proj";
qputenv("PROJ_LIB",PROJ_LIB_PATH.toLatin1());//Qt临时环境变量必须写在main中,在QApplication a(argc, argv);前面
// qDebug() <<"调试打印看看PROJ_LIB的值:" << qgetenv("PROJ_LIB");
...
}
解决方式二附加:
1、也可以和QGIS那样搞一个xxx.env(ini格式也行)文件再exe的同级路径,然后在QApplication a(argc, argv)这行代码前用QSettings类的对象去读取xxx.env文件。xxx.env文件中全是Key=Value这种格式写的键值对。
2、还可以尝试一下这种,把这个项目需要的环境变量路径中的资源例如地图加载需要的db文件、一堆dll、icon格式文件和env文件都放到exe附近的文件夹中。程序启动main函数启动后先用QSettings对象加载env文件中的一个确认的路径的键值对,如果项目的路径被移动了,就修改这个env文件中的键的值,再加载用qputenv加环境变量。*好处:*这样可以保证exe打包后不需要用户配置环境的