Use SQLite in Qt
SQLite is a lightweight, file-based database that needs no separate server process, which makes it a perfect fit for desktop applications that want to store data locally. Qt ships with a built-in SQLite driver as part of its SQL module, so you can talk to a database without pulling in any third-party dependency. This post walks through the few steps required to set it up and run your first queries.
Note: This post has been updated for Qt 6. Qt’s SQL API has stayed source-compatible across major releases, so the original steps still apply —
QT += sql, theQSQLITEdriver, andQSqlQuerybehave the same on modern Qt as they did when this was first written.
Enabling the SQL module
Qt keeps its database classes in a separate module that is not linked by default. To pull it in, add the following line to your project’s .pro file and rebuild:
QT += sql
Wrapping the database in a manager class
Rather than scattering connection code across the project, it is cleaner to hide the database behind a small manager class. The header below exposes just enough to open the database, delete it, and report the last error that occurred:
#include <QtSql/QSqlDatabase>
#include <QtSql/QSqlError>
class DatabaseManager {
public:
DatabaseManager();
~DatabaseManager();
public:
bool openDB();
bool deleteDB();
QSqlError lastError();
private:
QSqlDatabase db;
};
Opening and removing the database
QSqlDatabase::addDatabase("QSQLITE") selects the SQLite driver, and setDatabaseName() points it at a file on disk. If that file does not exist yet, SQLite creates it the first time you call open(). Whenever a call fails, lastError() gives you a human-readable description through QSqlError::text(), so it is worth surfacing it to the caller. Because an SQLite database is nothing more than a single file, deleting it is just a matter of closing the connection and removing that file:
bool DatabaseManager::openDB() {
// Find QSLite driver
db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("database_name_here");
// Open database
return db.open();
}
QSqlError DatabaseManager::lastError() {
// If opening database has failed user can ask
// error description by QSqlError::text()
return db.lastError();
}
bool DatabaseManager::deleteDB() {
// Close database
db.close();
return QFile::remove("database_name_here");
}
Running queries
Once the database is open, every statement goes through a QSqlQuery. For one-off statements such as creating or dropping a table, exec() takes the SQL string directly. When you insert user-supplied or otherwise dynamic data, however, prefer the prepared form with addBindValue(): it keeps the values properly escaped and protects you from SQL injection, instead of concatenating strings by hand. The example below creates a table, inserts a file record both ways, and finally drops the table:
QSqlQuery query;
// Create a new table
query.exec("CREATE TABLE filelist(fullpath VARCHAR PRIMARY KEY, timestamp VARCHAR)");
// Prepare file Information to insert
QFileInfo currentFile = ...;
QString filepath = currentFile.absoluteFilePath();
QString timestamp = currentFile.lastModified().date().toString("yyyy-MM");
// Insert a record by building the SQL string directly
query.exec("INSERT INTO filelist VALUES('" + filepath + "', '" + timestamp + "')");
// Or, more safely, bind the values to a prepared statement
query.prepare("INSERT INTO filelist VALUES(?, ?)");
query.addBindValue(filepath);
query.addBindValue(timestamp);
query.exec();
query.exec("DROP TABLE filelist");
That is all it takes: enable the SQL module, open a connection through the SQLite driver, and drive everything else with QSqlQuery. From here you can read rows back with query.next() and query.value() to display the stored data in your application.
The Disqus comment system is loading ...
If the message does not appear, please check your Disqus configuration.