Qt filename to bundled resource - qt

I have built a package in Qt that uses the external gdal library to query a raster file. I want to bundle the raster with my application and had hoped to do that in a qrc resource file.
Problem is that gdal wants a filename:-
const char *pzFileName = nullptr;
GDALAllRegister();
.
.
pzFileName = "/opt/mapping-data/SRTM/my_dem.tif";
testDataSet = (GDALDataset *) GDALOpen(pzFileName,GA_ReadOnly);
Is there a way I can bundle this file with my Qt app such that the filename is known on every platform? As gdal will have no idea of a "qrc/..." type url.

I would copy out the resource to a temporary file each time at the start of your application. GDAL seems to rely heavily on files and file names. You might use something like this:
QFile f(":/resources/file.txt");
QTemporaryFile::createNativeFile(f); // Returns a pointer to a temporary file

Related

Using QPluginLoader but throwing error:can't find the dll

I add resource file to Qt project like this:
and I use QPluginLoaderin cpp file:
QPluginLoader pluginLoader(":/dll/colorbar_plugin.dll");
It keeps throwing err:can't find dll file.
QPluginLoader expects a file name, not a URL. Additionally the file is expected to be located in the systems library search paths. Try putting your DLL in the same path as the executable and try this:
QPluginLoader pluginLoader("colorbar_plugin");
If you really must ship your DLL as a ressource, add your resource path to the search paths (including the qrc:).

How can I add the qrc import path for qtquick plugin?

I have built a static Qt library and want to use it deploy my app with a standalone exe. After one day effort, I have known that the qtquick plugin can not be static include into exe.
I need copy some folders in qml folder to my exe directory to let the exe can show GUI.
So I want to know which file my exe need, I deleted files in those folders one by one to get it known. The real needed file is just a plugins.QMLTYPES file and a qmldir file.
And then I found the import path of QQmlApplicationEngine can be changed, I output the QQmlApplicationEngine.importPathList() and one of paths is just the qml folder in Qt installed path. So I think this is the place where Qt get the search path of plugins.QMLTYPES file and qmldir file.
If all I think is correct, I can just copy the folders I need into qrc file and use QQmlApplicationEngine.addImportPath("qrc:/foldersIwant") to let exe can import what it need on runtime. And because qrc is compiled into exe, I can get rid of those folders and let my exe standalone.
But after I do this in my code, app still can not find the files it need even the output of QQmlApplicationEngine.importPathList() has the path I put into and I have also checked my path according to Load qmldir from QRC file.
Here is the code:
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.addImportPath(QStringLiteral("qrc:/import/qtquick/"));
qDebug()<<engine.importPathList();
engine.load(QUrl(QStringLiteral("qrc:/qml/main.qml")));
return app.exec();
}
Here is a part of my qrc file
Is there anything wrong in my deductive?
Further research:
I have add
engine.addImportPath(QDir::currentPath() + QDir::separator() + "custom");
and move all folders into custom folders, it can run successfully. And the exe which doesn't have this line can not run with custom folder. So I'm wondering the "search" behavior can not be applied to qrc file ?
Finally, I get the answer. The result shows all my thoughts are correct!
Below is what I had tried and you can just read the end to get the clear steps.
My aim is to compile a standalone qml2 application exe.
In qml1, I can build static Qt library and compile my app with it.
In qml2, the exe can be compiled in same way. But if I run it without Qt-Runtime. It just do not have any window shown on Windows OS (and also show nothing in other OS). I have googled so many informations and found this problem troubled many people since Qt5.0. Now it is Qt5.5, they still haven't repaired it. So I need copy folders in QT_INSTALLED_PREFIX/qml to the root directory of my app to let my app show GUI.
Althrough the problem will be solved in Qt5.6 (https://codereview.qt-project.org/#/c/114835/), I can't wait for so long (Qt5.6 will be released at the end of this year). So I decide to package the files by myself.
And I see this question by chance :Load qmldir from QRC file. It told me that qmldir file can be include into qrc file and the Qml engine can search into those directory. So I think, the QML files can also be included into qrc file.
But the first thing is to find where the qml2 be imported, when I looking into QQmlApplicationEngine's document, I found addImportPath function and I told myself that it must be the key of finding the import path. The document tells me everything:
QStringList QQmlEngine::importPathList()
const Returns the list of
directories where the engine searches for installed modules in a
URL-based directory structure.
For example, if /opt/MyApp/lib/imports is in the path, then QML that
imports com.mycompany.Feature will cause the QQmlEngine to look in
/opt/MyApp/lib/imports/com/mycompany/Feature/ for the components
provided by that module. A qmldir file is required for defining the
type version mapping and possibly QML extensions plugins.
By default, the list contains the directory of the application
executable, paths specified in the QML2_IMPORT_PATH environment
variable, and the builtin Qml2ImportsPath from QLibraryInfo.
After I delete the Qml2ImportsPath in importPathList at runtime, I made a recurrence of the bugs that app do not show any GUI.
And the document of addImportPath tells my that it can accept qrc url. So I add all the files in qml just like the question described above. But I still cannot see any GUI.
After several days of thinking. I found the pic I posted in question do not have qmldir files! That's a bug of Qt Creator. I add files using Add Existing Directory... and set the filter to *, it still cannot include qmldir file. So I add it into qrc file by xml code.
When I think this time it must work, it just gave me nothing. Just when I was going to give up, a thought occurred : it won't waste me more time to check whether qrc:/import/qtquick/ is valid.
The result is false, there must be a mistake in my qrc usage. I change the prefix and save the qrc with Qt Creator. I found the qrc file cannot use the path like D:/Qt/Qt-5.5-static/qml/Qt/labs/folderlistmodel/plugins.qmltypes, it is changed by Qt Creator to Qt/labs/folderlistmodel/plugins.qmltypes. At this time, everything works perfect!
Thanks for you reading my story. Here is a conclusion of steps for solving this problem:
Copy all folders in QT_INSTALLED_PREFIX/qml to your project folder, it is good to put them under a parent folder not the root folder.
Write some code to get all files' relative path except the .lib files and
.prl files.
Create a new .qrc file and include it in .pro file. Include all files into this .qrc file. I wrote a small program to generate the xml.
Add the import path using addImportPath method of QQmlApplicationEngine.
Build and enjoy.

Why do some DLL files need an additional .lib file for linking?

I have a question about library linking and .lib files...
this is the context:
OS = Windows
IDE = QT
I have created a DLL: MyLib.dll.
To use that library in my QT project, I only have to include an include path, a link to the library and use the header files:
LIBS += "C:\myPath\MyLib.dll"
INCLUDEPATH += "C:\myPath"
HEADERS += \
../myPath/MyLib_global.h \
../myPath/mylib.h
I am using a third party dll in my project: third.dll
If I do the same as in the above example, it does not work:
LIBS += "C:\myPath\third.dll"
The third party DLL comes with a .lib file "third.lib", which I apparently need to use together with the DLL.
Why is that? Why do some DLL libraries need a .lib file but other DLL libraries don't?
Could it be that the .lib is a static library accessing the DLL?
Thanks a lot!
My answer may not be specific to the context but would be useful to most developers asking the same question. This was answered by Anthony Williams
What is inside .lib file of Static library, Statically linked dynamic library and dynamically linked dynamic library?
You don't need a .lib file to use a dynamic library, but without one
you cannot treat functions from the DLL as normal functions in your
code. Instead you must manually call LoadLibrary to load the DLL (and
FreeLibrary when you're done), and GetProcAddress to obtain the
address of the function or data item in the DLL. You must then cast
the returned address to an appropriate pointer-to-function in order to
use it.
The lib file is an import library file, which allows the final executable to contain an import address table (IAT) by which all DLL function calls are referenced. Basically, allowing the functions to be looked up.
You can read about it here.
To have Qt generate the lib, add this to the .pro: -
CONFIG+= staticlib
Here's some documentation on how to create libraries.
Why is that? Why do some DLL libraries need a .lib file but other DLL libraries don't?
There are two types in linking dll :
Load time dynamic linking [ Implicit ]
Run time dynamic linking [ Explicit ]
If you using run time dynamic linking of dll the .lib is not used
But, for load time dynamic linking of dll the.lib file is used

Qt QPixmap constructing with qstring filename

I need to initialize a qpixmap object with its file directory
It works if I do the following:
image = new QPixmap("C:/Users/Administrator/Desktop/maze/HTetris-build-Desktop_Qt_5_0_1_MinGW_32bit-Debug/untitled/c12.bmp");
and it works with as well:
image = new QPixmap("/Users/Administrator/Desktop/maze/HTetris-build-Desktop_Qt_5_0_1_MinGW_32bit-Debug/untitled/c12.bmp");
But this is just too long and too specific.
I have put c12.bmp in the same file as the project itself. But
image = new QPixmap("c12.bmp");
simply does not work.
Since this project needs to be portal, how can I do!!!!!!!
Thanks guys for help
Consider to put your file into resource file (qrc) or put your file near your executable file, because your "c12.bmp" is searched in runtime and must be in the same with executable directory.
You file must be in the file where your application is executed (runtime directory) that can be different than the directory of the executable.
You can use resource files for the portablity (your pixmap will be "embedded" in your binary).
http://qt-project.org/doc/qt-4.8/resources.html

QMake OBJECTS issue after clean

I have a precompiled object file, say myObjectFile.o. Inside my .pro file I have a block of code like this:
mac {
...
OBJECTS += myObjectFile.o
}
This works great for linking in the object file with the rest of the project, but there is a fatal issue. If I do a clean this object file gets deleted. And since it's precompiled, when I try to build again I get a linking error until I copy the file back into my projects directory (I actually have a system call in my .pro file to copy the file so I just run qmake again).
This problem is annoying and causes some issues with our continuous integration server. Basically, I'm looking for a way I can link precompiled object files into my code.
You do this by adding the object files in LIBS rather than OBJECTS:
mac {
...
LIBS += myObjectFile.o
}
The contents of LIBS are passed to the linker as-is, which makes it possible to include object files in it.

Resources