Qt 提供了 QtSql 模块来提供平台独立的基于 SQL 的数据库操作。这里我们所说的“平台独立”,既包括操作系统平台,又包括各个数据库平台。另外,我们强调了“基于 SQL”,因为 NoSQL 数据库至今没有一个通用查询方法,所以不可能提供一种通用的 NoSQL 数据库的操作。Qt 的数据库操作还可以很方便的与 model/view 架构进行整合。通常来说,我们对数据库的操作更多地在于对数据库表的操作,而这正是 model/view 架构的长项。
Qt 使用QSqlDatabase
表示一个数据库连接。更底层上,Qt 使用驱动(drivers)来与不同的数据库 API 进行交互。Qt 桌面版本提供了如下几种驱动:
驱动 | 数据库 |
QDB2 | IBM DB2 (7.1 或更新版本) |
QIBASE | Borland InterBase |
QMYSQL | MySQL |
QOCI | Oracle Call Interface Driver |
QODBC | Open Database Connectivity (ODBC) - Microsoft SQL Server 及其它兼容 ODBC 的数据库 |
QPSQL | PostgreSQL (7.3 或更新版本) |
QSQLITE2 | SQLite 2 |
QSQLITE | SQLite 3 |
QSYMSQL | 针对 Symbian 平台的SQLite 3 |
QTDS | Sybase Adaptive Server (自 Qt 4.7 起废除) |
不过,由于受到协议的限制,Qt 开源版本并没有提供上面所有驱动的二进制版本,而仅仅以源代码的形式提供。通常,Qt 只默认搭载 QSqlite 驱动(这个驱动实际还包括 Sqlite 数据库,也就是说,如果需要使用 Sqlite 的话,只需要该驱动即可)。我们可以选择把这些驱动作为 Qt 的一部分进行编译,也可以当作插件编译。
如果习惯于使用 SQL 语句,我们可以选择QSqlQuery
类;如果只需要使用高层次的数据库接口(不关心 SQL 语法),我们可以选择QSqlTableModel
和QSqlRelationalTableModel
。本章我们介绍QSqlQuery
类,在后面的章节则介绍QSqlTableModel
和QSqlRelationalTableModel
。
在使用时,我们可以通过
QSqlDatabase::drivers();
找到系统中所有可用的数据库驱动的名字列表。我们只能使用出现在列表中的驱动。由于默认情况下,QtSql 是作为 Qt 的一个模块提供的。为了使用有关数据库的类,我们必须早 .pro 文件中添加这么一句:
QT += sql
这表示,我们的程序需要使用 Qt 的 core、gui 以及 sql 三个模块。注意,如果需要同时使用 Qt4 和 Qt5 编译程序,通常我们的 .pro 文件是这样的:
QT += core gui sql greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
这两句也很明确:Qt 需要加载 core、gui 和 sql 三个模块,如果主板本大于 4,则再添加 widgets 模块。
下面来看一个简单的函数:
bool connect(const QString &dbName) { QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE"); // db.setHostName("host"); // db.setDatabaseName("dbname"); // db.setUserName("username"); // db.setPassword("password"); db.setDatabaseName(dbName); if (!db.open()) { QMessageBox::critical(0, QObject::tr("Database Error"), db.lastError().text()); return false; } return true; }
我们使用connect()
函数创建一个数据库连接。我们使用QSqlDatabase::addDatabase()
静态函数完成这一请求,也就是创建了一个QSqlDatabase
实例。注意,数据库连接使用自己的名字进行区分,而不是数据库的名字。例如,我们可以使用下面的语句:
QSqlDatabase db=QSqlDatabase::addDatabase("QSQLITE", QString("con%1").arg(dbName));
此时,我们是使用addDatabase()
函数的第二个参数来给这个数据库连接一个名字。在这个例子中,用于区分这个数据库连接的名字是QString("conn%1").arg(dbName)
,而不是 "QSQLITE"。这个参数是可选的,如果不指定,系统会给出一个默认的名字QSqlDatabase::defaultConnection
,此时,Qt 会创建一个默认的连接。如果你给出的名字与已存在的名字相同,新的连接会替换掉已有的连接。通过这种设计,我们可以为一个数据库建立多个连接。
我们这里使用的是 sqlite 数据库,只需要指定数据库名字即可。如果是数据库服务器,比如 MySQL,我们还需要指定主机名、端口号、用户名和密码,这些语句使用注释进行了简单的说明。
接下来我们调用了QSqlDatabase::open()
函数,打开这个数据库连接。通过检查open()
函数的返回值,我们可以判断数据库是不是正确打开。
QtSql 模块中的类大多具有lastError()
函数,用于检查最新出现的错误。如果你发现数据库操作有任何问题,应该使用这个函数进行错误的检查。这一点我们也在上面的代码中进行了体现。当然,这只是最简单的实现,一般来说,更好的设计是,不要在数据库操作中混杂界面代码(并且将这个connect()
函数放在一个专门的数据库操作类中)。
接下来我们可以在main()
函数中使用这个connect()
函数:
int main(int argc, char *argv[]) { QApplication a(argc, argv); if (connect("demo.db")) { QSqlQuery query; if (!query.exec("CREATE TABLE student (" "id INTEGER PRIMARY KEY AUTOINCREMENT," "name VARCHAR," "age INT)")) { QMessageBox::critical(0, QObject::tr("Database Error"), query.lastError().text()); return 1; } } else { return 1; } return a.exec(); }
main()
函数中,我们调用这个connect()
函数打开数据库。如果打开成功,我们通过一个QSqlQuery
实例执行了 SQL 语句。同样,我们使用其lastError()
函数检查了执行结果是否正确。
注意这里的QSqlQuery
实例的创建。我们并没有指定是为哪一个数据库连接创建查询对象,此时,系统会使用默认的连接,也就是使用没有第二个参数的addDatabase()
函数创建的那个连接(其实就是名字为QSqlDatabase::defaultConnection
的默认连接)。如果没有这么一个连接,系统就会报错。也就是说,如果没有默认连接,我们在创建QSqlQuery
对象时必须指明是哪一个QSqlDatabase
对象,也就是addDatabase()
的返回值。
我们还可以通过使用QSqlQuery::isActive()
函数检查语句执行正确与否。如果QSqlQuery
对象是活动的,该函数返回 true。所谓“活动”,就是指该对象成功执行了exec()
函数,但是还没有完成。如果需要设置为不活动的,可以使用finish()
或者clear()
函数,或者直接释放掉这个QSqlQuery
对象。这里需要注意的是,如果存在一个活动的 SELECT 语句,某些数据库系统不能成功完成connect()
或者rollback()
函数的调用。此时,我们必须首先将活动的 SELECT 语句设置成不活动的。
创建过数据库表 student 之后,我们开始插入数据,然后将其独取出来:
if (connect("demo.db")) { QSqlQuery query; query.prepare("INSERT INTO student (name, age) VALUES (?, ?)"); QVariantList names; names << "Tom" << "Jack" << "Jane" << "Jerry"; query.addBindValue(names); QVariantList ages; ages << 20 << 23 << 22 << 25; query.addBindValue(ages); if (!query.execBatch()) { QMessageBox::critical(0, QObject::tr("Database Error"), query.lastError().text()); } query.finish(); query.exec("SELECT name, age FROM student"); while (query.next()) { QString name = query.value(0).toString(); int age = query.value(1).toInt(); qDebug() << name << ": " << age; } } else { return 1; }
依旧连接到我们创建的 demo.db 数据库。我们需要插入多条数据,此时可以使用QSqlQuery::exec()
函数一条一条插入数据,但是这里我们选择了另外一种方法:批量执行。首先,我们使用QSqlQuery::prepare()
函数对这条 SQL 语句进行预处理,问号 ? 相当于占位符,预示着以后我们可以使用实际数据替换这些位置。简单说明一下,预处理是数据库提供的一种特性,它会将 SQL 语句进行编译,性能和安全性都要优于普通的 SQL 处理。在上面的代码中,我们使用一个字符串列表 names 替换掉第一个问号的位置,一个整型列表 ages 替换掉第二个问号的位置,利用QSqlQuery::addBindValue()
我们将实际数据绑定到这个预处理的 SQL 语句上。需要注意的是,names 和 ages 这两个列表里面的数据需要一一对应。然后我们调用QSqlQuery::execBatch()
批量执行 SQL,之后结束该对象。这样,插入操作便完成了。
另外说明一点,我们这里使用了 ODBC 风格的 ? 占位符,同样,我们也可以使用 Oracle 风格的占位符:
query.prepare("INSERT INTO student (name, age) VALUES (:name, :age)");
此时,我们就需要使用
query.bindValue(":name", names); query.bindValue(":age", ages);
进行绑定。Oracle 风格的绑定最大的好处是,绑定的名字和值很清晰,与顺序无关。但是这里需要注意,bindValue()
函数只能绑定一个位置。比如
query.prepare("INSERT INTO test (name1, name2) VALUES (:name, :name)"); // ... query.bindValue(":name", name);
只能绑定第一个 :name 占位符,不能绑定到第二个。
接下来我们依旧使用同一个查询对象执行一个 SELECT 语句。如果存在查询结果,QSqlQuery::next()
会返回 true,直到到达结果最末,返回 false,说明遍历结束。我们利用这一点,使用 while 循环即可遍历查询结果。使用QSqlQuery::value()
函数即可按照 SELECT 语句的字段顺序获取到对应的数据库存储的数据。
对于数据库事务的操作,我们可以使用 QSqlDatabase::transaction()
开启事务,QSqlDatabase::commit()
或者QSqlDatabase::rollback()
结束事务。使用QSqlDatabase::database()
函数则可以根据名字获取所需要的数据库连接。
83 评论
🙁 泪流满面,终于等到数据库这一天了,跪--
不好意思哦~
😛 😛 支持
哦,太好了,终于有数据库了。。。。特别是sqlite。。。
另外,请教一下,最近官方源里好像有qt5了,今天总算可以放心下载安装。不过,我找不到qt5的demo和doc啊?下载好的qt creator 里面没有这两个东西。doc只有简单介绍而己,请问我要安装哪个包才能给qtcreator捆绑起来?
Qt5 的 demo 和 doc 在安装包里面就有的,不大清楚从安装源安装是什么名字。如果你直接下载安装包安装,QtCreator 和 Qt5 是设置好的,不需要额外的配置。
Qt5应该是不带编译好的demo了,只带了demo源码,如果想看,只能在QtCreator的入口里或者是在demo源码的目录下,自己把源码编译一下运行起来看。这样倒是也挺好。用什么编什么
如果没有这么一个连接,系统就会抱错
一个错别字。
已经修改过了,感谢指出!
请教豆子及各位高手一个问题:我编了下面这段打开数据库的程序,程序运行结果可以打开(open!),其中的"YY\SQLEXPRESS"和"master"是实际存在的hostname和dbname,但不知道为什么我任意乱写一个不存在的hostname或dbname,程序运行结果仍然是可以打开数据库?谢谢!
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setHostName("YY\SQLEXPRESS");
db.setDatabaseName("master");
if(db.open())
{
qDebug()<<"Open!";
db.close();
}
else
{
qDebug()<<"Error"<<db.lastError().text();
}
你使用的是 SQLITE 数据库,这个数据库不存在主机和数据库名字的概念。所以设置 host 实际是没有效果的。看你的数据库主机名字像是 SQL Server,所以你应该加载 SQL Server 的驱动才可以。
谢谢豆子指点,我的数据库确实是SQL Server,但是我把QSQLITE改为QODBC后,编译程序是会提示错误:qodbc driver not loaded。我用的是Qt5.0.1,我在网上查了很多,别人说Qt5中没有QODBC的驱动文件,我就按网上的办法,重新安装了Qt4.7.3,它里面就有QODBC的驱动文件,我就把这4个文件(两个.dll两个.a)拷贝到Qt5.0.1中的spldrivers文件夹中,可是编译后还是会提示错误:qodbc driver not loaded。
Qt4 的代码与 Qt5 不是二进制兼容的,所以你不能直接把 Qt4 的驱动复制到 Qt5 中使用。如果你的 Qt5 没有附带 ODBC 的二进制版本(不过豆子在 Qt5.1.1 (OpenGL) 中的确发现了 qsqlodbc.dll,但是没有测试能不能加载成功,理论上应该没问题),你需要自己编译 ODBC 驱动。如果你安装了 Qt5 的源代码包,你会在 Src/qtbase/src/sql/drivers 里面找到 QODBC 的源代码,然后尝试编译 QODBC(你可以在文档中找到编译方法;或者这里)。需要注意的是,你编译 QODBC 使用的编译器必须同 Qt 的编译版本一致。比如你安装的是 VS2010 版本的 Qt5,那么你必须使用 VS2010 的编译器进行编译,然后把编译好的 dll 复制到 sqldrivers 文件夹下就可以了。
已按照你的提示解决了问题,十分感谢!真搞不懂为什么qt5.0.1中没有qsqlodbc.dll?
这个不大清楚,没准儿是忘记了,还是由于协议的问题?
那我用的是Qt5.2.1 mingw 咋解决啊
那就用 mingw 编译呗
豆子你好,请教一个问题,是关于botan的,我用Qt5.0.1(Qtcreator2.6.2, mingw47)打开qt-creator-2.0.1-src中的botan.pro,然后build,但是为什么只生成Botand.dll和ilbBotand.a两个文件?正确的是应该生成四个文件:Botan.dll 、libBotan.a 、Botand.dll、libBotand.a四个文件。谢谢!
带有 d 的是 debug 版本,大概因为你的 pro 文件中没有添加 DEBUG 之类的宏。至于这个宏这么写,就要去看看文档了。没有 debug 版本其实也没有关系,只是不能调试。
我把botan.pro文件中的TEMPLATE = subdirs改为TEMPLATE = lib后,生成了其余的两个文件:Botan.dll 、libBotan.a .但和之前的那两个文件不在同一文件夹。
我用insert语句向数据库中插入一条记录,记录中有一个是自增的字段id,在sql server中可用通过下面语句获得自增的id。
如:INSERT INTO jobs (job_desc,min_lvl,max_lvl) VALUES ('Accountant',12,125) SELECT @@IDENTITY AS 'Identity'
但是:QSqlQuery query;
QString strSql = 上面语句;
query.exec(strSql);//返回true
if(query.next())//j返回false
{
}
直接query.value(0)也得不到值;
请问如果获得自增的id
直接使用 QSqlQuery::lastInsertId() 函数获取试试看。
谢谢,sqlserver不行,我最后用存储过程实现了。
您好,请问有时间的话能不能把这个插件静态编译一下,不知道为什么 我这边直接使用静态编译的Qt编译出来的静态库无法使用,就算把libsqlitecipher.a和libsqlitecipherd.a文件放入plugins\sqldrivers下面,运行后依然没有这个插件的驱动!
一直报这个table ..... already exists Unable to execute statement怎么解决??
小白了,懂了。。
怎么弄啊不懂
同遇到这个问题,想不明白,懂的人说说,谢谢!
也是懂了
您好,请问QVariantList 是不是可以用QLIst代替啊
QVariantList
就是typedef QList<QVariant>
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
说myql 驱动没有加载,但是在E:\Qt\Qt5.3.1\5.3\mingw482_32\plugins\sqldrivers 存在qsqlmysql.dll 文件 我copy到 qt creator 目录下 还是说mysql 驱动没有加载 什么意思啊?
但是 打印 支持mysql 驱动啊
会不会是版本问题?你说的“打印支持”,是输出的已经加载的驱动列表吗?
是的 available Device 里面有QMYSQL
但是我用的都是QT5.3.1的版本 不过安装了个QT5.2的版本
会不会是版本的问题?你是说插件和 Qt 版本不一致?这个具体我没有试过,方便的话可以发一个测试程序到 devbean#outlook.com
哈哈,从你的豆子空间学到这里来了。
请教下豆子:
我QT4.8.6+VS2010。
我想编译QMYSQL的,可官方教程里在QT的plugins里有mysql及mysql.pro,可我的文件里却没有。
请教下我该如何去编译QMYSQL?
如果没有的话,可以到 git 仓库将 QMYSQL 源代码 clone 下来进行编译。有可能在安装 Qt 的时候没有选择安装 source。
博主,您好:
请问一下,使用qt5.4在vs2010下,怎么给数据库添加中文字符啊?
不知道是什么数据库啊?中文字符一般是可以直接添加的,需要注意的是编码要一致。
QSqlDatabase: QMYSQL driver not loaded
QSqlDatabase: available drivers: QSQLITE QMYSQL QMYSQL3 QODBC QODBC3 QPSQL QPSQL7
豆子老师 这是什么意思
没有加载 MySQL 驱动,一般是没有找到。
HEAP[mainwin.exe]: Invalid address specified to RtlValidateHeap( 005F0000, 00658F60 )
老师,你好,一直报这个错误怎么办?
这种错误一般是因为内存问题,检查下是不是哪里有对象未创建之类
你好,我在使用exec()函数的时候,如果网络断开,或者数据库所在的服务器资源紧张如cpu占用比较高的时候,exec()会卡主,很长时间都不返回。可否通过设置参数来解决这个问题,谢谢~~
早期版本没有超时的设置(最新版 5.5 没有研究),一般使用一个 QTimer 定时器做超时。
怎么做啊,纠结了好久都没整出来,您有这方面的例子么,给一个喽。
楼主你好,我用qt连接远程的mysql,提示连接成功,但是执行query.exec("select * from production"); 结果是false,即查询不到数据,但我的production表是有数据的,我用同样代码读取本地的production表,结果能读取。。。这是什么问题
可以用 lastError() 看看有什么错误
楼主你好,问下QSqlite怎么存储QPath,QPoint,Qlist及自定义的一些类型,如果不行,用其他数据库能做到么
数据库中存储的应该是值,而不是类型。比如 QPoint,在数据库中应该存入 x 和 y 的具体值,读取之后重新新建一个 QPoint 对象,然后赋值。直接存储对象也是可以的,需要首先将对象序列化,读取时要反序列化。不过,这样的话,数据库中的数据就是特定平台的了,对人读也不友好。
请问豆子,我用你的代码后编译时出现错误 Driver not Loaded Driver not Loaded的Database Error错误,百度各种找不到解决办法,用的是qt-opensource-windows-x86-android-5.5.1,在另一台电脑上安装后还是一样的错误,毫无办法啊!
这个应该是数据库驱动没有找到,看看是不是写错了驱动名字还是什么原因?
你好豆子,这个问题解决了,是把 QSqlDatabase db=QSqlDatabase::addDatabase("QSQLITE", QString("con%1").arg(dbName));
用前面那个 QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName(dbName); 这样分开写后就好了,也不知道为什么用第一个方法写就会出现那种奇怪错误。
请问大神 程序运行时数据库载入失败要怎么解决啊
qt错误0*00000a38指令引用的内存,不能为read,不知道要怎么解决,求大神指导
void loginDialog::on_loginBtn_clicked()
{
model = new QSqlTableModel(this);
model->setTable("user");
model->select();
int i;
for(i=0;irowCount();i++)
{
QSqlRecord record=model->record(i);
if(record.value(1)==ui->userLineEdit->text()&&
record.value(2)==ui->pwdLineEdit->text())
{
QString str1="登录成功";
QString str2=record.value(1).toString();
QMessageBox::information(this,"提示",str2+str1,QMessageBox::Yes);
accept();
}
else if(record.value(1)==ui->userLineEdit->text()&&
record.value(2)!=ui->pwdLineEdit->text())
{
QMessageBox::information(this,"提示","密码输入有误",QMessageBox::Yes);
ui->userLineEdit->clear();
ui->pwdLineEdit->clear();
ui->userLineEdit->setFocus();
return;
}
QMessageBox::warning(this,"提示","用户不存在,请注册",QMessageBox::Yes);
ui->userLineEdit->clear();
ui->pwdLineEdit->clear();
ui->userLineEdit->setFocus();
return;
}
}
请问应该怎样改,输入用户名和密码显示用户名不存在
请问下,QT下怎么使用exec()的回调形式啊
长时间不访问数据库会自动断开连接。在终端里面执行语句会自动重新连接,不需要输入密码之类的;但是在QT里面不行,请问QSqlDatabase有相关属性设置吗?
还是只能在每次执行语句前都去查询数据库连接状况,如果没有连接调用一次连接函数?或者用一个定时器定时去执行保持数据库连接?
数据库重连一般是需要在连接时单独设置。
QSqlDatabase
提供了setConnectOptions()
函数,用于设置连接参数。可以依据使用的数据库提供具体的参数,例如,MySQL 提供了MYSQL_OPT_RECONNECT=1
这样的参数,用于重连。具体需要查阅数据库的相关文档。另外,如果不起作用,可以考虑用SELECT 1
这样的语句进行测试,如果查询失败,认为已经断开,那么就先close()
再open()
来试一下豆子老师请问下,我在ubuntu16.04 和 qt5.6 64位环境下遇到一个问题,在示例中的出现查看错误的lasterror函数编译clang给出下面的错误。注释lasterror这个函数可以编译成功。
calling 'last Error' with incomplete return type 'QSqlError'
bool Database::connectDB(const QString &dbName)
{
m_database = QSqlDatabase::addDatabase("QSQLITE");
m_database.setDatabaseName(dbName);
if (!m_database.open())
{
qDebug() << "Database: connect failed" << m_database.lastError().Text(); //这里编译出错
return false;
}
return true;
}
可能是你没有 include QSqlError
豆子,你好!我想请教你一个问题,我使用sql模型数据来连接数据库操作,在提交时数据有生僻字,提交后显示的是个问号"?",我使用的字符集是gbk,能帮忙分析下吗?
是不是 gbk 编码问题,sqlite 默认使用 utf-8 编码,你换成 utf-8 试试看看怎么样呢?
豆子老师你好,我按教程写的数据库连接,生成了可执行文件,可执行文件在装了Qt的电脑上可连接数据库,换台没装Qt的电脑就显示数据库打开失败,应该是在db.open那一句那儿,相关的dll我是都拷贝过去了的?请问怎么回事呢?
相关的数据库包括libgcc_s_dw2-1.dll mingwm10.dll qsqlite4.dll qsqlodbc4.dll Qtcore4.dll QtGui4.dll QtOpenGL4.dll QtSql4.dll QtSvg4.dll QtTest4.dll qwt.dll 另有一个数据库文件与可执行文件在同一文件夹下。我在debug和release版本下都遇到了这个问题,没有百度到可用的方案。
默认情况下,qsqlite4.dll、qsqlodbc4.dll 应该是在 sqldrivers 文件夹下,并不是与 exe 同目录下的。这些属于 Qt 插件,有自己的插件目录结构,应该按照 Qt 的目录结构放置
发现一个文字错误:
这里我们所说的“平台独立”,既包括操作系统平台,有(又?)包括各个数据库平台...
感谢指出!
有个疑问:connect()函数创建一个数据库连接QSqlDatabase db,那么在函数作用域之外db不是自动失效了吗?为什么下面的QSqlQuery query还能用到这个连接呢?
QSqlDatabase 是类似单例的形式,相当于一种注册的操作,所以是可以使用的
博主,请教一个问题:1个qsqlquery怎么与qsqldatabase关联起来?
这个问题的起因是连接mysql数据库时出现错误:连接数据库已经正常了,但是query执行sql语句后提示“driver not loaded”的错误,后来查了一下有个博客说:
----------------
说明你的query在创建的时候没有和qsqldatabase建立起关联.正确的方法是声明qsqldatabase后就声明query.如果你希望一 个连接能够和多个query关联使用如下语法:QSqlQuery query(db),db是QSqlDatabase的实例名.
----------------
两种办法我都试了,都不行:
1. 在自己定义的MySql中声明成员变量QSqlDatabase db_,然后再声明QSqlQuery query_
2.在自己定义的MySql中声明成员变量QSqlDatabase db_,然后再声明QSqlQuery query(QSqlDatabase db_)
如果QSqlDatabase和QSqlQuery变量都已经声明,那后面有什么办法把这两者关联起来吗?
找到原因了:query必须在db已经连接之后关联才有用。
QSqlQuery query_temp(db_);
query_ = query_temp;
大神,我用的是qt5.5连的本地数据库是SQLITE,之前一直没问题,今天突然莫名其妙有一个insert语句不好用,调试出给的错误是QSqlError("", "", ""),看了毫无方向,求帮忙啊,程序里有很多insert语句,只有这一句不好用
这个不知道怎么回事,可能是哪里有了错误,需要看代码才会知道
QSqlDatabase myDB = QSqlDatabase::addDatabase("QODBC");
QString QtDBTest = QString (伺服器设定就不看了);
myDB.setDatabaseName(QtDBTest);
myDB.open();
QSqlQueryModel *model = new QSqlQueryModel();
model->setQuery("SELECT * FROM Robot_Condition");
model->query().exec();
model->setHeaderData(0, Qt::Horizontal, "ID");
model->setHeaderData(1, Qt::Horizontal, "X_axis");
model->setHeaderData(2, Qt::Horizontal, "Y_axis");
model->setHeaderData(3, Qt::Horizontal, "angle");
model->setHeaderData(4, Qt::Horizontal, "battery");
QTableView *view = new QTableView;
view->setWindowTitle("QSqlQueryModel");
view->setModel(model);
view->show();
myDB.close();
然而显示的表是空白的 , 把myDB.close();删除就可以显示出表的数据
但却会卡顿 表的资料量也不大 请问该怎么解决?
model->query().exec(); 这句是没有的 没改好
QSqlDatabase::addDatabase("QSQLITE"); // addDatabase()到底是创建一个数据库连接,还是创建一个数据库?
按照我的理解,创建一个数据库连接是数据库文件已经存在,创建一个连接与这个数据库文件连上;创建一个数据库则是数据库不存在,要创建一个数据库文件。
例中的代码执行后会生成一个数据库文件,那这就不是创建数据库连接,而是创建数据库了啊。
对于 sqlite 是这样的,如果数据库文件存在就直接连接,不存在则创建。如果是其它类型数据库,比如 mysql 之类,不存在就会直接报错的
谢谢回复,我用1个有数据的数据库文件试了下,确实是这样的,之前还担心如果数据库已经存在的话会被覆盖。
main() 那段代码有个问题:运行后.exe会一直显示在任务管理器中,不会自动关闭,这是什么情况?
因为我们在 main() 函数中开启了事件循环(通过调用 exec()),数据库连接之后没有其它操作,事件循环不会自动退出,所以会一直执行。这一段代码实际并不需要事件循环,所以你将 return a.exec(); 改成 return 0; 就可以了
豆子,我发现id自增那里,我用不了AUTOINCREMENT,只能用Identity,这是为什么?
Identity 和 AUTOINCREMENT 都是数据库的语法。一般 SQL Server 支持 Identity,MySQL 支持 AUTOINCREMENT。可能是你使用的数据库不同的关系。
两次if (connect("demo.db")),第一次叫connect返回后,创建的数据库不会在栈上释放掉么。如果没的话,第二次叫不会覆盖嘛