qt操作php 数据库操作崩溃

1159人阅读
一. 数据库操作 1.MySql驱动编译 在windows系统中,我们在mingw,MySql5和Qt4的环境中编译MySql驱动主要有以下几个步骤: (1)下载 http://www.qtcn.org/download/mingw-utils-0.3.tar.gz ; (2)将mingw-utils-0.3.tar.gz解压缩,将bin目录下的reimp 工具复制到 mingw目录下的bin 里,如果Dev-C++就复制到C:\Dev-Cpp\bin目录下 (3)将MySql安装目录下的include和lib目录拷贝到没有空格的路径下,比如C: \mysql下; (4)打开Qt Command Prompt,分别执行以下命令: cd c:\mysql\lib\opt reimp -d libmysql.lib dlltool -k -d libmysql.def -l libmysql.a 这样在c:\mysql\lib\opt目录下就会生成一个libmysql.a文件; (5)接下来执行以下命令:&& cd %QTDIR%\src\plugins\sqldrivers\mysql qmake -o Makefile "INCLUDEPATH+=C:\MYSQL\INCLUDE" "LIBS+=C :\MYSQL\LIB\OPT\LIBMYSQL.a" mysql.pro 找到%QTDIR%\src\plugins\sqldrivers\mysql\下的Makefile.release 和 Makefile.debug文件,去掉-llibmysql项再make编译,这下便会在%QTDIR%\plugins\sqldrivers目录下 面生成libqsqlmysql.a, qsqlmysql.dll这两个文件,然后在程式的.pro文件中添加QT+=sql并在程式开头包含#include 就能操作数据库了。 2.完全解决数据库存储中文和Qt程式显示数据库中文及中文字符串的问题 (1)数据库和表及表里的字符相关字段(varchar, char, text等)都要使用gbk_chinese_ci这种方式,不这样做也能,但这样做,会省非常多麻烦。 (2)重新编译Qt的MySQL驱动,需要修改src / sql / drivers / mysql / qsql_mysql.cpp文件。要修改的部分如下:第一百零八行的codec函数&& static QTextCodec* codec(MYSQL* mysql) { return QTextCodec::codecForName("GBK");//增加部分 #if MYSQL_VERSION_ID &= 32321 && QTextCodec* heuristicCodec = QTextCodec :: codecForName ( mysql_character_set_name ( mysql ) ); if (heuristicCodec) && return heuristicC #endif return QTextCodec::codecForLocale(); } (3)然后,重新编译qt的mysql驱动在Qt程式main函数中app后面开头处加入下面三句,加上这三个是省得不必要的麻烦&& QTextCodec::setCodecForLocale(QTextCodec::codecForName("GBK")); QTextCodec::setCodecForCStrings(QTextCodec::codecForName("GBK")); QTextCodec::setCodecForTr(QTextCodec::codecForName("GBK")); (4)在Qt数据库连接后,运行"SET NAMES &UTF8&"语句或"SET NAMES &GBK&"。&& db = QSqlDatabase::addDatabase("QMYSQL"); db.setHostName("localhost"); db.setDatabaseName("yourdatabase"); db.setUserName("yourusername"); db.setPassword("yourpassword"); db.open(); db.exec("SET NAMES &UTF8&"); 经过以上四步,就能在Qt程式中直接使用中文字符串,而且能直接使用中文字符串出入于程式和数据库之间 3.连接MySql数据库 QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL"); db.setHostName("localhost"); db.setDatabaseName("test"); db.setUserName("root"); db.setPassword("******"); bool ok = db.open();
链接QSLite数据库:
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE"); 4.SELECT操作 QSqlQ int numR query.exec("SELECT * FROM scores ORDER BY id ASC"); while (query.next()) { QString name = query.value(0).toString();//query.value()的参数只能是index int salary = query.value(1).toInt(); label = setText(QString::number(salary)+name);//测试查询数据的行数 if (db.driver()-&hasFeature(QSqlDriver::QuerySize)) { && numRows = query.size(); } else { && // this can be very slow && query.last(); && numRows = query.at() + 1; } } 5.INSERT操作 (1)直接插入(一条记录) QSqlQ query.exec("INSERT INTO employee (id, name, salary) VALUES (1001, &Thad Beaumont&, 65000)"); (2)通过&:字段&操作 QSqlQ query.prepare("INSERT INTO employee (id, name, salary) VALUES (:id, :name, :salary)"); query.bindValue(":id", 1001); query.bindValue(":name", "Thad Beaumont"); query.bindValue(":salary", 65000); query.exec(); (3)通过&?&操作 QSqlQ query.prepare("INSERT INTO employee (id, name, salary) VALUES (?, ?, ?)"); query.addBindValue(1001); query.addBindValue("Thad Beaumont"); query.addBindValue(65000); query.exec(); 6.UPDATE操作 QSqlQ query.exec("UPDATE employee SET salary = 70000 WHERE id = 1003"); 7.DELETE操作 QSqlQ query.exec("DELETE FROM employee WHERE id = 1007"); 8.transaction()操作 有时为了执行一系列复杂的操作,使用QSqlDatabase::transaction()能加快速度 //database为QSqlDatabase对象 if(database.driver()-&hasFeature(QSqlDriver::Transactions)) //测试数据库是否支持Transactions, { database.transaction(); query.exec("SELECT name FROM scores WHERE id=19"); if(query.next()) { &&&&& //str = query.value(0).toString(); &&&&& str = "中国"; &&&&& query.exec("INSERT INTO scores(name) VALUES(&"+str+"&)"); } <mit(); } 注意,如果str为中文字符串,在SQL语句中需要标明&str&(用单引号括起),如果是英文或数字字符串,能不加单引号(指的是包含在双引号内的SQL语句) 9.使用SQL Model类 QSqlQueryModel&&一个只读的读取数据库数据的模型 QSqlTableModel&&一个可读写的单一表格模型,能不用写SQL语句 QSqlRelationalTableModel&&QSqlTableModel的一个子类 这些类都继承于QAbstractTableModel,而他们又都继承于QAbstractItemModel (1) QSqlQueryModel的使用 QSqlQueryM querymodel.setQuery("SELECT * FROM scores ORDER BY id ASC"); for (num=0;numquerymodel.rowCount();num++) { str += QString::number(querymodel.record(num).value("id").toInt()); str += " "; str += querymodel.record(num).value("name").toString(); //注意这里的value()参数能是index(索引)也能是字段名,前面QSqlQuery的value()参数只能是index str += "\n"; } label-&setText(str); (2) QSqlTableModel的使用 ① 读取数据 QSqlTableM
tablemodel.setTable("scores"); tablemodel.setFilter("id & 10"); tablemodel.setSort(0,Qt::DescendingOrder); tablemodel.select(); for (num=0;numtablemodel.rowCount();num++) { str += QString::number(tablemodel.record(num).value("id").toInt()); str += " "; str += tablemodel.record(num).value(1).toString(); str += "\n"; } label-&setText(str); ② 修改数据 QSqlTableM tablemodel.setTable("scores"); tablemodel.setFilter("id & 10"); tablemodel.setSort(0,Qt::DescendingOrder); tablemodel.select(); for (num=0;numtablemodel.rowCount();num++) { QSqlRecord record = tablemodel.record(num); record.setValue("name",record.value("name").toString()+"2"); tablemodel.setRecord(num,record); } if(tablemodel.submitAll()) label-&setText("修改成功!"); else label-&setText("修改失败!"); 或能用setData()来修改,代码如下: QSqlTableM tablemodel.setTable("scores"); tablemodel.setFilter("id & 10"); tablemodel.setSort(0,Qt::DescendingOrder); tablemodel.select(); tablemodel.setData(tablemodel.index(2,1),"data修改"); if(tablemodel.submitAll()) &&& label-&setText("修改成功!"); else &&& label-&setText("修改失败!"); ③ 删除数据 tablemodel.removeRows(row, 5); //removeRows()第一个参数为要删除的第一行的行数,第二个参数为要删除的总行数; tablemodel.submitAll(); //注意,利用QSqlTableModel修改或删除数据,最后都要使用submitAll()执行更改 ④ 插入数据 QSqlRecord record = tablemodel.record(); record.setValue("name","插入的"); tablemodel.insertRecord(2,record); //注意,此处插入利用insertRecord()函数,该函数第一个参数为插入到tablemodel的第几行,第二个参数为记录,注意这里的记录一 定要和tablemodel中的记录匹配,故QSqlRecord record = tablemodel.record();另外,插入操作不用submitAll(),因为,insertRecord()返回bool值。 10.使用QTableView 开头处要使用#include QTableView *view = new QTableView(); view-&setModel(&model); view-&setEditTriggers(QAbstractItemView::NoEditTriggers); view-&show();
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:72576次
积分:1031
积分:1031
排名:第17369名
原创:12篇
转载:75篇
评论:16条
(3)(3)(3)(1)(2)(1)(3)(6)(5)(1)(1)(3)(1)(1)(4)(1)(1)(1)(1)(3)(7)(1)(6)(3)(2)(1)(4)(4)(10)(7)qt数据库操作(使用qt creator编写) - 下载频道
- CSDN.NET
&&&&qt数据库操作(使用qt creator编写)
qt数据库操作(使用qt creator编写)
使用qt编写的数据库建立、插入数据,很有借鉴价值
若举报审核通过,可奖励20下载分
被举报人:
举报的资源分:
请选择类型
资源无法下载
资源无法使用
标题与实际内容不符
含有危害国家安全内容
含有反动色情等内容
含广告内容
版权问题,侵犯个人或公司的版权
*详细原因:
您可能还需要
移动开发下载排行2345人阅读
Keeping the GUI
Responsive
原文作者:
Jason Lee @
里的人们经常提到一个反复出现的问题:长操作期间
界面无响应。这个问题不难解决,并且有多种应对方案,因此我在这里列出一些针对不同情况的可能的解决方案。
第一件事是列出这个问题域并且列出可以采取的解决方案。前面涉及的这个问题可能以两种形式出现。第一种情况是程序在执行计算密集型任务,也就是需要经过一系列操作才能得到最后的结果。比如快速傅里叶变换。
另一种情况是程序必须在已经触发的活动(比如从网络上下载东西)结束后才能继续算法的下一步。这种情况,就本身而言,通过使用
是比较容易避免的,因为大多数的异步操作在
中可以采用信号和槽的机制来实现,所以你可以将之连接到一个槽中来继续算法的下一步。
在计算过程中(无论以何种方式使用信号和槽)所有的事件处理都会被暂停。因此,
不会被刷新,用户输入不会被处理,网络活动停止以及定时器不运作&&程序看起来被冻结了并且,事实上,程序中不耗时的那部分也被冻结了。&长操作&是多长呢?任何使得程序无法即时响应用户的事情都算长。一秒钟是长,任何超过两秒钟的操作肯定太长了。
本文旨在保持程序功能,防止终端用户被一个不响应的
(以及网络和定时器)所惹恼。为了做到这个目标首先需要看看可能的解决方案和问题的主因。
我们可以通过两种方式来获取计算型任务的结果&&通过在主线程(单一线程方案)或者在单独的线程(多线程解决方案)进行计算。后者较多地为人所知并且在
中得到应用,但是有时候在使用单一线程会更好的情况下它也被滥用了。与主流观点相反,线程通常使你的程序变慢而非变快,因此除非你确定你的程序可以通过使用多线程变得更优良,否则不要因为你会就随处创建新线程。
该问题域可以看做是两种情形组成的。我们不一定能够将问题细化成更小的步骤、循环或者子问题(通常它不应该是一个整体)。如果问题可以细化,它们也不一定互相依赖。如果它们之间是独立的,我们可以任意处理它们。否则,我们必须同步我们的任务。最坏的情况下,我们只能一次处理一些并且只有上一步结束了才能开始下一步。充分考虑这些因素,我们可以选择不同的解决方案。
人工的事件处理
最基本的解决方案就是显示地要求
在计算过程的某个点处理悬挂事件。为此,需要周期性地调用
QCoreApplication::processEvents()
。以下是示例:
for (int i = 3; i &= sqrt(x) && isP i += 2) {
label-&setText(tr(&Checking %1...&).arg(i));
if (x % i == 0)
QCoreApplication::processEvents();
if (!pushButton-&isChecked()) {
label-&setText(tr(&Aborted&));
这种方法有明显的缺点。比如,假设你想并发地执行两个循环&&调用其中一个会暂定另一个,直到该调用结束(所以不能在不同任务之间不能分配计算量)。它也造成了程序对事件处理的延迟。更重要的是代码难以阅读和分析,因此这种方案只适合短而简单的、在单一线程中处理的问题,比如闪屏或短期操作监控。
使用任务线程
另一种不同的解决方案就是在单独的线程中执行长操作从而避免阻塞主事件循环。假如任务是由第三方库通过阻塞方式执行,这是特别有效的。在这种情况下,它是不可能去打扰
处理悬挂事件的。
一种可以完全控制独立线程的方式是使用
。可以继承它并且重写它的
函数,或者调用
QThread:exec()
来启动线程的事件循环,或者两者共用:继承然后必要的时候在
函数里调用
。可以通过信号和槽来连接主线程&&只要记住
QueuedConnection
会被使用到或者其它线程可能失去稳定性然后导致你的程序崩溃。
由于有很多多线程相关材料,所以这里不列举代码示例了,而把注意力集中在其它地方。
在本地事件循环中等待
要介绍的下一种处理等待异步任务结束的方案已经完结。这里,将要讨论如何在一个网络操作结束前阻塞程序流,并不阻塞事件处理。从本质上说,我们可以做的就是:
task.start();
while (!task.isFinished())
QCoreApplication::processEvents();
这叫做忙等待&&频繁判断一个条件是否满足。大多数情况下这是一个坏主意,它占用了全部
资源并且有着人工事件处理的所有缺点。
幸运的是,
有一个类来帮助我们处理这项任务:
QEventLoop
是程序和模态对话框在它们
调用里使用的相同的类。每个该类的实例都连接到主事件分发机制,并且一旦它的
函数激活,它就开始处理事件直到使用
我们利用这种机制结合信号和槽使得异步操作转化为同步操作&&我们可以开启一个本地事件循环然后通过特定对象的特定信号告知它结束退出:
QNetworkAccessM
QTimer tT;
tT.setSingleShot(true);
connect(&tT, SIGNAL(timeout()), &q, SLOT(quit()));
connect(&manager, SIGNAL(finished(QNetworkReply*)),
&q, SLOT(quit()));
QNetworkReply *reply = manager.get(QNetworkRequest(
QUrl(&http://www.qtcentre.org&)));
tT.start(5000); // 5s timeout
if(tT.isActive()){
// download complete
tT.stop();
// timeout
我们使用一个网络访问管理类获取远程
。由于它工作在异步方式,我们创建了一个本地事件循环来等待下载者的结束信号。此外,我们实例化一个定时器在五秒后来结束事件循环以免发生错误。通过连接合适的信号,提交请求和开始定时器,我们进入了新建的事件循环。对
的调用会在下载结束或者五秒结束后返回。我们通过判断定时器是否还在运作来判断是哪个原因引发结束。然后我们处理结果或者告知用户下载失败。
在这里需要注意另外两件事。一个通过
QxtSignalWaiter
类实现类似的解决方案是
项目的一部分。另外一件事是,对于一些操作而言,
提供了一系列的&等待&方法(比如
QIODevice::waitForBytesWritten()
)或多或少地做些和上面代码片段一样的事,但并没有运行一个事件循环。然而,&等待&方案会冻结
因为它们没有运行它们自己的时间循环。
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:523955次
积分:7783
积分:7783
排名:第765名
原创:185篇
评论:752条
文章:14篇
阅读:14782
文章:14篇
阅读:91671
(1)(1)(5)(3)(3)(1)(1)(2)(2)(4)(1)(1)(1)(3)(1)(3)(1)(1)(12)(5)(4)(4)(5)(10)(4)(3)(1)(1)(18)(5)(1)(4)(3)(1)(2)(1)(1)(1)(1)(1)(6)(6)(2)(4)(8)(4)(2)(10)(11)(7)(3)(3)(1)(6)}

我要回帖

更多关于 php 数据库操作 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信