我实际上正在使用Qt& SqlLite和我的问题是,即使是一个完全在sqllite3.exe上运行的请求也无法运行到我的程序中。我不断收到我设置的错误消息。我想知道它是否真的是一个代码问题,因为我可以实际连接到我的数据库,并且在将它们尝试到sqllite3.exe时请求正常工作。
数据库路径:
SQLLITE\musclelayout
DataHandler.cpp - 构造函数(经过许多有用的评论后编辑)
DataHandler::DataHandler(QMainWindow* mw, const QString& path)
{
databaseIsOpen = false;
database = QSqlDatabase::addDatabase("QSQLITE");
database.setDatabaseName(path);
qDebug() << "Opening database:" << path << "from" << QDir::currentPath();
qDebug() << "Does the file exist:" << QFileInfo::exists(path);
if(database.open())
{
qDebug() << "Database opened. Tables:" << database.tables();
databaseIsOpen = true;
}
else
{
QString msgTitle("Cannot login to '" + path + "'");
QMessageBox::StandardButton alertMsg;
alertMsg = QMessageBox::warning(mw, msgTitle, database.lastError().text(), QMessageBox::Ok);
}
}
道路完全错误:
Opening database: "SQLLITEmusclelayout" from "C:/Users/Tong3/Desktop/DEV/build-muscleLayout-Qt_5_8_0_mingw53_32-Debug"
Does the file exist: true
Database opened. Tables: ()
但是我不能写#SQLLITE \'#(不会编译),并且路径不会进入我的项目所在的位置。 真正的网址:
C:\Users\Tong3\Desktop\DEV\muscleLayout\SQLLITE\musclelayout
DataHandler - getTrainedMucleList()
vector<QString> DataHandler::getTrainedMuscleList(QMainWindow* mw)
{
vector<QString> tmp_array;
QSqlQuery query;
if(databaseIsOpen)
{
if(query.exec("SELECT * FROM trainedMuscle"))
{
while(query.next())
{
tmp_array.push_back(query.value("muscleName").toString());
}
}
else
{
QString msgTitle("Cannot load muscle list");
QMessageBox::StandardButton alertMsg;
alertMsg = QMessageBox::warning(mw, msgTitle, query.lastError().text(), QMessageBox::Ok);
}
}
else
{
QString msgTitle("Cannot login to database");
QMessageBox::StandardButton alertMsg;
alertMsg = QMessageBox::warning(mw, msgTitle, database.lastError().text(), QMessageBox::Ok);
}
return tmp_array;
}
感谢您花时间阅读我的新手代码, 祝你有愉快的一天。
答案 0 :(得分:2)
您没有正确使用QSqlQuery。
构造函数QSqlQuery(const QString &query = QString(), QSqlDatabase db = QSqlDatabase())
执行给定的query
。引用文档:
使用SQL查询和数据库db构造QSqlQuery对象。 如果未指定db或无效,则应用程序为默认值 使用数据库。 如果查询不是空字符串,它将是 执行。强>
虽然bool QSqlQuery::exec()
用于准备查询。仍在引用文档:
执行以前准备的SQL查询。如果查询,则返回true 执行成功;否则返回false。
您可以改用这些示例:
// The most complete form as you could bind values between prepare() and exec()
QSqlQuery query;
query.prepare("SELECT * FROM trainedMuscle");
query.exec();
// A shorter form for when you do not need to bind values
QSqlQuery query;
query.exec("SELECT * FROM trainedMuscle");
// The shortest form, the query is executed in the constructor,
// you do not need to call exec(). Use lastError() to check execution.
QSqlQuery query("SELECT * FROM trainedMuscle");
此外,SQLite是无服务器(https://www.sqlite.org/serverless.html),因此您可以更改打开数据库的方式,因为您不需要设置服务器:
database = QSqlDatabase::addDatabase("QSQLITE");
database.setDatabaseName(path);
if(database.open())
...
另外,鉴于您的意见,我怀疑您的路径存在问题,因此您可以添加一些调试输出以确保打开正确的SQLite数据库文件:
database = QSqlDatabase::addDatabase("QSQLITE");
database.setDatabaseName(path);
qDebug() << "Opening database:" << path << "from" << QDir::currentPath();
qDebug() << "Does the file exist:" << QFileInfo::exists(path);
if(database.open())
{
qDebug() << "Database opened. Tables:" << database.tables();
....
}
像QString path = "SQLLITE\"
这样的东西不会编译是正常的。反斜杠是一个转义字符,如果你想在一个字符串中放一个litteral反斜杠你需要加倍它。如果要编写Windows路径,可以编写:
QString path = "C:\\Users\\Tong3\\Desktop\\DEV\\muscleLayout\\SQLLITE\\musclelayout"; // Actually contains "C:\Users\Tong3\Desktop\DEV\muscleLayout\SQLLITE\musclelayout"
但是如果您使用Qt,则可以使用正斜杠作为目录分隔符编写Windows路径,如下所示:
QString path = "C:/Users/Tong3/Desktop/DEV/muscleLayout/SQLLITE/musclelayout";
之所以&#34;路径并没有进入我的项目所在的位置&#34;是程序的工作目录最初是从执行程序的位置设置的。它与可执行文件的位置和源的位置无关。
在程序中使用相对路径时,它们将相对于此工作目录进行解释。
作为开发人员,您无法控制初始工作目录的内容,因为它取决于用户启动程序的方式。但是,您可以在执行程序期间更改它。
在您的情况下,工作目录为C:/Users/Tong3/Desktop/DEV/build-muscleLayout-Qt_5_8_0_mingw53_32-Debug
。可以在&#34; Projects&#34;中的QtCreator中更改此选项。选项卡,在&#34;运行设置&#34;。
但是我认为最好不要使用相对路径,而是将SQLite数据库与应用程序放在一起(请参阅QCoreApplication::apllicationDirPath())或AppData文件夹(请参阅QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)),具体取决于用户是否愿意需要具有对数据库的写访问权。