Qt QList ASSERT failure after installing on others PCs - c++

I made a setup packadge of some program in Visual Studio 2008. So on my PC after installation everything works well. On others PC when you just click on database connection option it just crashes.
Well, here's the error
I think it appears at this line
database = QSqlDatabase::addDatabase("QPSQL");
in database initialization part because of message about DB apperas and everything seems work fine until this line.
Here's full function
void DatabaseManagement::initDatabase(){
QMessageBox::information(this, "error tracking step 5", " DB ADDED");
database = QSqlDatabase::addDatabase("QPSQL");
QStringList sdrivers = QSqlDatabase::drivers();
//output all avalible drivers
QString driver = sdrivers[0];
for(int i = 0; i< sdrivers.size();i++)
QMessageBox::information(this, "Driver info", sdrivers[i]);
}
database variable here is global for DatabaseManagement class.
Also in this class I got getDatabase function which returns database variable and I use it in other class, let say in mainClass (in case if this could be cause of the problem).
What coulbe be the cause of this problem? How could I solve that?
By the way, I use Qt 4.7.4
UPD:
Well, the problem solved! I forget to add sqldrivers folder! Of course I added all necessary .dlls but for some reason program see it only in this folder. Hope it could be helpful for somebody.
By the way DependencyWalker show taht nothing was wrong with not working version (without sqldrivers folder).

My guess would be that the problem lies here (A debugger would tell you more):
QStringList sdrivers = QSqlDatabase::drivers();
//output all available drivers
QString driver = sdrivers[0];
You're accessing sdrivers[0] without checking that sdrivers contains at least one element.
I assume you didn't deploy the Qt SQL plugins correctly and thus none is found on the other computer. So fix above code (guarding it with if (!sdrivers.isEmpty())) and deploy the plugins.

The problem is more likely this line: QString driver = sdrivers[0];
I guess you forgot to provide the sql-plugin folder? %YOUR-APP-PATH%/plugins/qpsql.dll
Try adding:
if(sdrivers.size() > 0)
QString driver = sdrivers[0];

Related

Can't open database using SQLite on an UWP written in C++

I am making an UWP in which I need to access a database. To do so I first downloaded and installed the SQL Universal Windows Platform from this link:
https://sqlite.org/download.html
After this was done I added it as a reference and included it in my code with:
#include <sqlite3.h> //Not sure if I need to make any other changes for this to work
To troubleshoot I have just a button and a textbox. This is the code that it's been run when the button is clicked:
int rc;
sqlite3 *testDB;
if (SQLITE_OK == (rc = sqlite3_open("signers.db", &testDB))) {
Message->Text = "It worked!";
}
else {
Message->Text = "Can't open Database";
}
signers.db it's a database that I created using SQLite so I could have some data to read from my program. Everytime I run the program the text "Can't open Database" appears. I've tried every solution that I see online but none seem to work for me thus I think that I overseeing something. I am fairly new at UWP and also at using databases.
If you need any additional information feel free to ask for it.
If you have the database in your package folder, then it is read-only. You need to use sqlite3_open_v2 and pass the SQLITE_OPEN_READONLY flag.
If you want to open the database for read / write then you need to copy it to your local folder first.
(Also make sure you actually have the database set to deploy; in the Properties window make sure it is set to Content and that it will be copied to the output directory).
According to
https://learn.microsoft.com/en-us/windows/uwp/files/file-access-permissions
you have some limitations to the location where the db file you want to open is located. sqlite itself should work. Try opening a db in a folder specified in the article.
Could also be just a corrupted db file. Did you try to create an empty one?

Qt QDir::current()

I had some code like this:
void MainWindow::saveData()
{
QDir oldDir=QDir::current();//this should return the main executable directory.Since there is no other place in my hole code where i temper with QDir.
QDir sess("Sessions");
if(!oldDir.exists("Sessions"))//if "Sessions" Dir doesn't exist
oldDir.mkdir("Sessions");//create it.
QDir::setCurrent(sess.absolutePath());
//some virtual code inside current Dir, which i didn't implement yet.
QDir::setCurrent(oldDir.absolutePath());//restore old dir
}
When I run my app firstly the code works perfectly.but in the second run, the first call to QDir::current(); returns the "Sessions" Dir and not the main executable Dir as it should be restored in the first run.actually i did manage to overcome this by adding one line at the biginning of the code, the following :
QDir::setCurrent(QCoreApplication::applicationDirPath());
Still I want to know why the first code didn't work.already checked for the documentation of the functions and found nothing.
QDir::current();//this should return the main executable directory
No it should not! Not unless you change it to point there first.
I'm dead serious when I'll say this: Yours is a myth, fantasy, whatever you call it, I have no idea what gave you the idea. Point me to a spec that says so. Oh, you can't, because there's no such spec, no such requirement. It's someone's twilight hour mirage that seems to perpetuate itself endlessly. If you heard it from someone, you have every right to be angry at them this very moment, for they did you a big disservice.
Generally speaking, for applications that are not normally started from the command line, the initial working directory can be anything and it will be platform- and session/system configuration dependent. For a typical GUI application, assuming any particular initial working directory is a fool's errand and completely misguided.
Once you change it to where you want it to point to, you of course have full control over it, but the initial working directory must be assumed to be random and out of your control.
For example, on Windows I can start your application through an Explorer shortcut where I can specify whatever startup folder I desire, and you have zero control over it. On OS X, Finder sets the working directory to something or another, IIRC to the folder where the app bundle resides. Again, you as a developer have no control over it unless there's some setting in the bundle that you could add to that effect, but that is platform-specific and will be ignored if your application is not started through Finder or bundle API mechanisms (they probably are called something else). And so on. It's completely arbitrary and it's pointless to depend on its initial value.
If you want to refer to the application's installation directory or executable directory, do so explicitly. Do not assume anything about the initial working directory of a GUI application.
I tried with the below code and it works fine for several runs.
The version details of Qt and OS may help.
Qt creator 3.3.2 (open source). Qt lib 5.4.1.Os windows 8.1
#include <QCoreApplication>
#include "QDir"
#include "qDebug"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QDir oldDir=QDir::current();
qDebug()<<QDir::current().absolutePath();
QDir sess("H:\\cuteapps\\session");
if(!oldDir.exists("H:\\cuteapps\\session"))//if "Sessions" Dir doesn't exist
oldDir.mkdir("H:\\cuteapps\\session");//create it.
QDir::setCurrent(sess.absolutePath());
qDebug()<<QDir::current().absolutePath();
return a.exec();
}
output 1:
"H:/cuteapps/build-untitled2-Desktop_Qt_5_4_1_MSVC2012_OpenGL_32bit-Debug"
"H:/cuteapps/session"
output 2:
"H:/cuteapps/build-untitled2-Desktop_Qt_5_4_1_MSVC2012_OpenGL_32bit-Debug"
"H:/cuteapps/session"
output 3:
"H:/cuteapps/build-untitled2-Desktop_Qt_5_4_1_MSVC2012_OpenGL_32bit-Debug"
"H:/cuteapps/session"

When connect to the database I get an error `driver not loaded`

First: I am using Qt v5.3.1 with MinGW 4.8.2, and Window 7 32bit platform.
When run my application in windows 7, I found it is working fine in connect to database only if Qt environment is installed, also when move the same application to another platform like windows xp by Virtual PC, unfortunately I found the connection to database fail too, and an error message appears driver not loaded, but the application works fine but without connection to database.
My attempts:
I have used QSqlDatabase::drivers() to check if sqlite supported
in the system, and the result was, sqlite database
supported with many other types.
I have used isValid() to check if there is a valid driver, but the
function return false, and this indicates that the database type is
not available or could not be loaded.
The following is the code that I use:
database.h
class database
{
public:
static QSqlDatabase db;
static QString dbPath;
database();
static void connect();
static bool openConnection();
static void CloseConnection();
static void removeDB();
};
database.cpp
QSqlDatabase database::db = QSqlDatabase::addDatabase("QSQLITE");
QString database::dbPath = "";
database::database(){
}
void database::connect(){
database::dbPath = "database.db";
database::db.setDatabaseName(database::dbPath);
}
void database::CloseConnection(){
database::db.close();
}
void database::removeDB(){
database::db.removeDatabase(database::db.defaultConnection);
}
Also I have checked if the database file exists or not, and also I have opened the connection to database.
database::connect();
if(QFile::exists(database::dbPath)){
if(database::db.open()){
ui->label->setText(ui->label->text() + "Connected.");
QSqlQuery qry;
qry.prepare("SELECT * FROM users");
qry.exec();
while(qry.next()){
ui->listWidget->addItem(qry.value("username").toString());
ui->listWidget->item(ui->listWidget->count()-1)->setData(Qt::UserRole, qry.value("id").toString());
}
database::CloseConnection();
}else{
ui->label->setText(ui->label->text() + "Failed to connect to database");
}
}else{
ui->label->setText(ui->label->text() + "Database file does not found");
}
I don't know what's the problem in the connection with database, everything is alright, and there is no missing files in my application, and the database file beside the executable file.
How to solve this problem ?
QSqlDatabase database::db = QSqlDatabase::addDatabase("QSQLITE");
This line is the problem. This is global code (code that gets run before main), which in turn attempts to load a Qt Plugin before a QCoreApplication instance has been created. This call will therefore fail.
Solution: leave it default-initialized and call addDatabase after creating a QCoreApplication.
Better solution: stop using global variables; you can open your DB connection in main and pass the connection handle to the classes which need it (also note that QtSql classes natively support the concept of a "connection name", so you can access that connection from everywhere, given the right name of the conection).
In Windows XP, \Program Files is not writable by normal users.
(Neither is it in Windows 7, but depending on the configuration, some paths might be redirected.)
Use QDesktopServices::DataLocation (Qt 4) or QStandardPaths::DataLocation (Qt 5).
database::dbPath = "database.db" means the database file beside the executable file or in the main directory of application"
This statement is false. The path you gave is relative to the current working directory, not to the location of the executable file. If the working directory and the executable's path happen to be the same, you merely ran into a coincidence that can't be depended on. Never mind that the executable's location is not writable, so there's no point in storing any variable data there!
You need to store that database somewhere else, and you must be explicit about where it's stored.

KDE writing (too many) in the console

I'm developping a Qt GUI application.
My problem is that I use the console for another thread (it write his comunication in it), and the main problem is that when I create a QFileDialog (in order to select a script file), KDE is wrinting useless informations (for me at least).
Is there a way to remove all possibility from my QFileDialog to write anything into the consolethat ? Is there a trick to switch main output to another (useless) target ?
My code (but I don't think it's really gonna help you) :
void MyGUI::setPathWithFileExplorer()
{
QFileDialog dlg;
dlg.resize(320,240);
QString fileName = dlg.getOpenFileName(this, tr("Open script file"), "~/", tr("Script Files (*.js)"));
if(fileName != "")
ui->editScriptPath->setText(fileName);
}
Output :
kded(21003) Mollet::KioSlaveNotifier::onDirectoryEntered: "trash:/"
kded(21003) Mollet::KioSlaveNotifier::onDirectoryLeft: "trash:/"
kded(21003) Mollet::KioSlaveNotifier::onDirectoryEntered:
"file://[PATH TO MY USER FOLDER]" kded(21003)
Mollet::KioSlaveNotifier::onDirectoryLeft:
"file://[PATH TO MY USER FOLDER]" kded(21003)
Mollet::KioSlaveNotifier::onDirectoryEntered:
"file://[PATH TO MY USER FOLDER]" kfilemodule(21676)
KSambaSharePrivate::testparmParamValue: We got some errors while
running testparm "Load smb config files from /etc/samba/smb.conf
Loaded services file OK. WARNING: The setting 'security=ads' should
NOT be combined with the 'password server' parameter. (by default
Samba will discover the correct DC to contact automatically). WARNING:
You have some share names that are longer than 12 characters. These
may not be accessible to some older clients. (Eg. Windows9x,
WindowsMe, and smbclient prior to Samba 3.0.) "
QInotifyFileSystemWatcherEngine::addPaths: inotify_add_watch failed:
Permission non accordée QFileSystemWatcher: failed to add paths:
/var/lib/samba/usershares
I would suggest using kdebugdialog and then Deselect All. Here you can see an inline screenshot on my machine.
Failing that, you could always use QFile to log your output into a dedicated file, and then monitor that in a separate prompt or application.
If you go down that way, you could even take a look at the logger functionality added in 5.2 if you happen to be able to use that version.

Problem with QHttp example qt 4.4.3

I'm trying to use QHttp for an update app. But there is a problem for me which I can't solve.
I try to download a file (works perfectly) but if there is no connection to the internet, the file is created but has 0 bytes. My old file is then overwritten with the empty file, which is not so good for the application trying to use the file. What I need is to check if the computer is connected to the internet.
Note: proxy may set. I used this example from Qt's homepage.
You should switch to the QNetworkAccessManager as Mike Suggested, here is an example of a slot on the finished() signal:
void ApplicationUpdate::replyFinishedhttpGetChangeLog(QNetworkReply* myReply) {
if (myReply->error() != QNetworkReply::NoError)
{
QByteArray returnedData = myReply->readAll();
if (returnedData.size() > 0) {
if( m_fileChangeLog->exists() )
{
m_fileChangeLog->close();
m_fileChangeLog->remove();
}
m_fileChangeLog->open(QIODevice::ReadWrite);
QDataStream out( m_fileChangeLog );
out.writeRawData(returnedData.data(), returnedData.size());
m_fileChangeLog->flush();
m_fileChangeLog->close();
}
}
}
Firstly, you should probably now be using QNetworkAccessManager rather than QHttp.
Using either of them, you should do a dummy query to a site you pretty much always know will be up (e.g. http://www.google.com/) and use that as a test to see if you have an internet connection.
A better way of doing this would be instead to use QNetworkAccessManager to read into a QByteArray and then check it isn't empty before writing to your file.
Whenever you write a file that might already exist, you should create a QTemporaryFile first, then, after successful download, rename it to the final name.
i ran into the same problem, after a bit of poking around, I've isolated the problem down to the project configuration file (.pro), in the broken configuration I was linking the networking library explicitly with the statement : "LIBS += -lQtNetwork". In the working configuration, I used the more formal (and qt compilant) approach of delcaring what Qt components are included in the project, like so: "QT = core gui network xml", adjust accordingly for your sitiation, the netowkring slots did not work on windows when explicitly linked but did work on linux. Using the qt compilant approach works on both platforms.