Solved Qt 5.10.0, msvc2015, windeployqt with -sql stops Qt from finding drivers
-
Hello Community,
I'm having some perplexing problems. My program runs fine from Qt Creator at first, but as soon as I use windeploy qt, I'm getting the following errors right at the start of the program, before the first line in my main method is reached:QSqlDatabase: QSQLITE driver not loaded QSqlDatabase: available drivers: QSqlDatabase: an instance of QCoreApplication is required for loading driver plugins
My windeployqt command is as follows: windeployqt.exe -qmldir <...> ./<executable> -sql -network
In my pro, QT += sql is present.
As the errors indicate, SQL functionality is indeed non present, including errors such as Could not open Database and Driver not loaded.Checking my executable folder after windeployqt, I can see that the sqldrivers folder is there and contains the relevant dlls.
I suppose it should be noted, that my the sql functions are in a dll and in its cpp file, the line
QSqlDatabase database = QSqlDatabase::addDatabase("QSQLITE");
is outside of any method, as in, it's a sort of global variable. Perhaps this is the cause of the error happening even before the main method is entered? But then, why would it only cause errors after executing windeployqt ... ?
My application is a QML application, so rather than directly instantiating QCoreApplication, I have an instance of QGuiApplication allocated on the heap, before any other SQL functions are called.Thank you for reading, I hope you can help me with this rather strange error :)
-
Hi and welcome to devnet,
Do you mean that
database
is a static variable ?If so, then it's wrong. There's absolutely no need for such a variable. The QSqlDatabase class is already some sort of singleton that manages the database objects you might create in your application.
-
Thank you for your response.
Truth be told, I'm a little puzzled by the dll's design, as it's not from me.
Here's a slightly larger excerpt from the cpp file in question for clarity:namespace vdb { namespace { QString path; QSqlDatabase database = QSqlDatabase::addDatabase("QSQLITE"); } void openDatabase(const QString &databasePath) //declared as DLL_DECL { //... database.setDatabaseName(/*...*/); if (!database.open()) //... } }
(The .h and .cpp files here do not declare a class)
In any case, do you think this could be responsible for the behavior?The solution would be to declare database locally as
QSqlDatabase database = QSqlDatabase::database(); //default connection
in every function that needs it, if I understand the documentation correctly?
If this is a fix, then the only mystery that remains is why it worked without using windeployqt ...
-
Since you are using only the default connection then there’s no need to retrieve the database object in each and every function you do a query with.
But indeed, it shouldn’t influence windeployqt.
Silly question, do you have several versions of Qt installed ? If so, are you sure you are using the correct one ?
-
Yes, I do have multiple versions installed, but I made sure to compile and windeploy with the correct ones.
In any case, with your advice, we were able to solve the issue:
void openDatabase(const QString &databasePath) { static bool initialized = false; QSqlDatabase database; if (!initialized) { database = QSqlDatabase::addDatabase("QSQLITE"); initialized = true; } else { database = QSqlDatabase::database(); }
With this, the error is gone and the program works both with and without windeployqt. As you said, we only use this in the openDatabase function.
Thank you for your advice! In retrospect the solution is rather obvious, but the strange behavior with windeploy really got us confused :)