我有一个项目要从 Visual Studio 迁移到 QtCreator。编译器相应地改变。现在是使用数据库的问题。所有这些都在工作室工作,但我不明白 QtCreator 和 MinGW 不喜欢什么。具体来说,问题归结为在处理 SQL 查询时,它没有看到表。如果您查看 SQLiteManager,那么所有表都已就位,并且执行查询并提供所需的输出。
问题在这里:
QVector<QStringList> DbManager::showNotes()
{
if (MattyNotesDb.isOpen())
{
QVector<QStringList> VectorOfNotes;
QueryConstructor SelectAll;
SelectAll.setTableName(QStringLiteral("Notes"));
SelectAll.setOrderByClause("NoteId", Descending);
QSqlQuery getNotesQuery;
if( getNotesQuery.exec(SelectAll.constructSelectQuery())) // exec возвращает false
{
while (getNotesQuery.next()) // соответственно тоже возвращает false
{
QStringList Fields;
for (int i = 0;i < 9;i++)
{
Fields.push_back(getNotesQuery.value(i).toString());
}
VectorOfNotes.push_back(Fields);
}
}
else
{
QMessageBox::critical(NULL, QObject::tr("Error"), getNotesQuery.lastError().text()); // no such table. Unable to execute statement
}
return VectorOfNotes;
}
else
{
showIsNotOpenError();
return QVector<QStringList>();
}
}
数据库连接:
bool DbManager::connect(const QString & path)
{
MattyNotesDb = QSqlDatabase::addDatabase("QSQLITE");
MattyNotesDb.setDatabaseName(path); // path="MattyNotes.sqlite"
if(QFile::exists(path)) // true
{
if (!MattyNotesDb.open()) // open=true, то есть if(false)
{
QMessageBox::critical(NULL, QObject::tr("Error"), MattyNotesDb.lastError().text());
MattyNotesDb.close();
return false;
}
return true;
}
else
{
return false;
}
}
提出要求:
QString QueryConstructor::constructSelectQuery()
{
QString ResultQuery = "";
if (TableName != "")
{
ResultQuery.append("SELECT ");
if (WhatToSelectFieldNames.isEmpty())
{
ResultQuery.append("*");
}
else
{
for (int i = 0;i < WhatToSelectFieldNames.length()-1;i++)
{
ResultQuery.append(" " + WhatToSelectFieldNames[i] + ",");
}
ResultQuery.append(WhatToSelectFieldNames.last());
}
ResultQuery.append(" FROM " + TableName + constructWhereEqualsClause() + " " + OrderByClause);
}
return ResultQuery; // "SELECT * FROM Notes ORDER BY NoteId DESC; "
}
UPD: 问题出在文件路径中。如果您手动输入完整路径,则一切正常。
一。
QString PathToDb = QCoreApplication::applicationDirPath() + "/MattyNotes.sqlite";
该选项最终将 PathToDb 变量设置为 "C:/Users/Matty/Documents/QtCreator/build-MattyNotes-Desktop_Qt_5_7_1_MinGW_32bit-Debug/debug/MattyNo" 文件夹是正确的,但为什么被截断了?
2.
QString PathToDb = QDir::currentPath() + "/MattyNotes.sqlite";
这个选项赋值为“C:/Users/Matty/MattyNotes.sqlite” 一般来说,我想知道中间文件夹去了哪里。
3.
QString PathToDb = QFileInfo(".").absolutePath() + "/MattyNotes.sqlite";
此选项给出“C:/Users/MattyNotes.sqlite”
发生了什么?如何只指定一个相对路径,以便一切都在不同的机器上运行?
还有一个问题:为什么
if(QFile::exists(path)) // true
if (!MattyNotesDb.open()) // open=true, то есть if(false)
如果数据库实际上没有打开,这些行是否返回 true?
尚未为查询分配数据库。试试这样:
QSqlQuery::QSqlQuery(QSqlDatabase 数据库)
更新。当从 Qt Creator 下启动应用程序时,更改的环境将应用于程序。当前目录不是可执行文件所在目录,而是上一级目录。要确定,请在 .pro 文件中写入:
该程序将显示完整路径。这是放置数据库文件的位置。通常,如果指定的数据库文件不存在,sqlite 驱动程序会创建一个新的数据库文件。因此,很可能是数据库已经打开,但指定的表不在其中。当通过双击文件正常启动应用程序时,使用正常环境。在这种情况下,数据库文件必须在同一文件夹中,必要的 DLL 文件(Qt5Core.dll、Qt5Sql.dll、Qt5Widgets.dll 等)也必须位于该文件夹中,并且数据库驱动程序文件必须位于sqldrivers 文件夹(qsqlite.dll 好像位于目录
$$[QT_INSTALL_PLUGINS]/sqldrivers)如果您不希望 Qt Creator 将更改后的环境应用于程序,请单击左侧的“项目”按钮,然后在底部的“运行时”中选择“系统环境”。