注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

长风明志的博客

不要也不能做下一个谁,应该且可以做第一个自己

 
 
 

日志

 
 

关于QT学习  

2011-07-28 19:24:06|  分类: QT编程 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

1.   调试信息通过控制台输出:


在pro文件中加入win32:CONFIG += console即可让调试信息通过控制台输出
在qt中输出调试信息可以使用qWarning,qDebug等

2.   解析xml文件时:


 对于命名空间,即带有冒号的item,如果需要读取完整的字符串可以使用QXmlStreamReader的成员函数qualifiedName(),
 项目文件中(.pro)增加QT += xml的设置

3.   中文操作乱码问题,字符编码的设置,在main函数中增加如下代码


QTextCodec::setCodecForLocale(QTextCodec::codecForName("GBK"));

QTextCodec::setCodecForCStrings(QTextCodec::codecForName("GBK"));

QTextCodec::setCodecForTr(QTextCodec::codecForName("GBK"));


4.   数据库操作,mysql


  编译qt的mysql链接库(windows和linux的区别)[详细说明]【http://www.yafeilinux.com/?p=80
  将 ’ , ” 转义成/’,/”
  项目文件中(.pro)增加QT += sql的设置

5.   正则表达式的使用


字符串中第一个全数字的子串([0-9]?[0-9]*[0-9])
详细说明:http://blog.csdn.net/Blue_Light/archive/2010/01/18/5206538.aspx

6.   延时调用
  QTimer::singleShot( XXXX ms, this, SLOT(func()))

#include <QtSql>    
#include <QMessageBox>    
#include <QTextStream>    
QTextStream out(stdout);    
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");    
db.setHostName("localhost");    
db.setDatabaseName("test");    
db.setUserName("root");    
db.setPassword("xxxxxx");    
if(!db.open())    
{    
 QMessageBox::critical(0,QObject::tr("Database Error"),db.lastError().text());    
return a.exec();    
}    
QSqlQuery query;    
query.exec("SELECT * FROM t_homedata");    
while(query.next())    
{    
QString id = query.value(0).toString();    
 QString type = query.value(1).toString();    
QString data = query.value(2).toString();    
out << id << ", " << type << ", " << data <<endl;    
}   

使用QScrollArea作为预览对话框

TestDraw.h

#ifndef TESTDRAW_H

#define TESTDRAW_H

#include <QtGui/QDialog>

#include "ui_TestDraw.h"

#include <QPainter>

#include <QPixmap>

#include <QScrollArea>

#include <QLabel>

class TestDraw : public QDialog

{

Q_OBJECT

public:

TestDraw(QWidget *parent = 0, Qt::WFlags flags = 0);

void drawPixmap();

~TestDraw();

private:

Ui::TestDrawClass ui;

QPixmap *pPixmap;

QScrollArea *pScrollArea;

private slots:

void on_pushButton_clicked();

};

#endif // TESTDRAW_H

TestDraw.cpp

#include "TestDraw.h"

TestDraw::TestDraw(QWidget *parent, Qt::WFlags flags)

: QDialog(parent, flags)

{

ui.setupUi(this);

}

void TestDraw::drawPixmap()

{

pPixmap = new QPixmap(400,300);

QPainter paint(pPixmap);

paint.setPen(Qt::black);

paint.drawRect(50,50,100,100);

}

TestDraw::~TestDraw()

{

}

void TestDraw::on_pushButton_clicked()

{

drawPixmap();

if(pPixmap != NULL)

{

  QLabel *pLabel = new QLabel;

  QPixmap pixmap(*pPixmap);

  pLabel->setPixmap(pixmap);

  pScrollArea = new QScrollArea;

  pScrollArea->setWidget(pLabel);

  pScrollArea->show();

 

QSqlDatabase类详细介绍

QtSql模块提供了一个平台无关且数据库无关的访问SQL数据库的接口。

    Qt中的每个数据库连接用一个QSqlDatabase对象来表示;Qt使用不同driver来和各种不同数据库的API进行通讯。

    QSqlQuery提供了直接执行任意SQL语句的特性;此外还提供了两个高层次的无需SQL命令的数据库接口:QSqlTableModel和QSqlRelationalTableModel
Section 1. Connecting and Querying

    在执行SQL命令前,必须先建立好同数据库的连接。

    静态函数QSqlDatabase::addDatabase()用于创建一个新的QSqlDatabase对象,函数的第一个参数指定了Qt该选择哪个Driver来访问数据库。

    在对创建的QSqlDatabase对象设定好host name,database name ,username和password后,需要调用open()函数来建立到数据库的连接。

    一旦到数据库的链接建立好后,就可以通过QSqlQuery::exec()来执行底层数据库所支持的任意SQL语句了。

    QSqlQuery::next()返回查询结果集中的下一行,而QSqlQuery::value()则返回当前行中的某一项的值,以QVariant的形式返回。

    可以使用QSqlQuery::isActive()来检查SQL语句的执行是否出现错误。

placeholder
    QSqlQuery::prepare() 
    QSqlQuery::bindValue() or QSqlQuery::addBindValue()
    QSqlQuery::exec()

    Qt支持数据库中transaction(事务)这个概念。transaction()用于启动transaction,而commit()或rollback()用于结束transaction。

    静态函数QSqlDatabase::database(),返回指定连接所对应的QSqlDatabase对象。

    QSqlDatabase::driver() 返回该连接底层所使用的dirver
    QSqlDatabase::hasFeature()可用来查询底层数据库是否支持某项特性。

    Qt允许在一个程序中创建多个数据库连接,这中情况下在执行SQL语句时,需要为QSqlQuery的构造函数传入要执行该语句的数据库对应的QSqlDatabase对象。

    与QSqlQuery相比,QSqlTableModel提供了一个更高层次、更抽象的接口,可以避免使用原始的SQL命令。

    QSqlTableModel::record() & QSqlTableModel::value()

    QSqlTableModel::insertRow() & QSqlTableModel::setData()

    QSqlTableModel::submitAll() ,于其他model不同,在使用QSqlTableModel时,必须调用submitAll()来强制所有的修改都写入数据库。

    当需要处理外键(foreign key)时,需要使用QSqlRelationalTableModel而不是QSqlTableModel。

    对于使用了SQL相关类的应用程序,需要在对应的.pro中添加下面一行:"QT     +=sql",这样在链接时会将QtSql库链入。


Qt中使用第三方的数据库(Sqlite)存储并读取文件本体        在网上找了一下关于如何在数据库中存储文件本体(一般是关于image)的内容,但是发现大多数的做法都是存储文件相应的路径,需要该文件的时候通过路径查询,感觉那样的做法的话,文件只是在一种抽象的方式被存储在了数据库中,本体并没有被存储,这样做可能是出于效率和数据库大小的考虑(本人对数据库知道的不多)。因为前段时间对QT比较感兴趣,然后发现其中可以使用第三方的数据库,于是尝试了下。

 

(1)创建数据库连接

bool MyDatabase::CreateConnection()

{

db = QSqlDatabase::addDatabase("QSQLITE");

db.setDatabaseName("mydb.db");

if (!db.open()) {

qDebug()<<" can't open database >>>>>> mydb.db";

exit(-1);

}

return true;

}

使用第三方数据库Sqlite,数据库名字为mydb.db,而后就是打开数据库了。

 

(2)创建存储说需要的表

bool MyDatabase::CreateTable()

{

QStringList tableList = db.tables();

 

QSqlQuery query(db);

if(!tableList.contains("files"))

{

QString createTable = "create table files (id integer primary key,"

"filename varchar(128) unique, filecontent blob)";

if(!query.exec(createTable))

{

qDebug()<<query.lastError();

exit(-1);

}

}

return true;

}

查看是否存在相关的表,不存在,则通过"create table files (id integer primary key,filename varchar(128) unique, filecontent blob)";创建files表。

 

(3)存储文件名为

bool MyDatabase::StoreFile(QString FileName)

{

QSqlQuery query(db);

 

QFile File(FileName);

if(File.open(QIODevice::ReadOnly)){

QByteArray &tdata = File.readAll();

QByteArray data = qCompress(tdata,9);

query.prepare("INSERT INTO files (id,filename,filecontent)"

"VALUES(NULL,:filename,:filecontent)");

query.bindValue(":filename", FileName);

query.bindValue(":filecontent", data);

 

if(!query.exec())

{

qDebug()<<query.lastError();

return false;

}

}

else

{

return false;

}

return true;

}

基本思想就是把名为FileName的文件装换成为QByteArray,然后使用第三方的zlib进行最高等级的压缩,然后存储

 

(4)从数据库中

bool MyDatabase::GetFile(QString FileName)

{

QSqlQuery query(db);

query.prepare("select filecontent from files");

query.exec();

query.next();

QByteArray tdata = query.value(0).toByteArray();

QByteArray data = qUncompress(tdata);

 

QFile File(FileName);

if(File.open(QIODevice::WriteOnly))

{

File.write(data);

File.close();

}

else

{

return false;

}

 

return true;

}

因为仅仅是尝试,所以只需读取一个并把它命名为FileName。基本思想是把存储在数据库中的内容转化为QByteArray,然后解压,写入到文件中。


QSqlDatabase dbconn = QSqlDatabase::addDatabase("QSQLITE", "testSQLite");   
    dbconn.setDatabaseName("test.db3"); //当前目录下的test.db3数据库文件   
    //SQLite数据库文件可用SQLite的命令行工具(c:/sqlite3.exe 数据库名)或用SQLite GUI工具创建,SQLiteSpy   

    if(!dbconn.open())   
    {   
           
        return;   
    }   

    QTableView *view;   
    QSqlTableModel *model;   
    view = new QTableView();   
    model = new QSqlTableModel(this,dbconn);   
    model->setTable("test");   
    model->select();   
    view->setModel(model);  

也可以直接访问内存得到:如

QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName(":memory:");
    if (!db.open()) {
        QMessageBox::critical(0, qApp->tr("Cannot open database"),
            qApp->tr("Unable to establish a database connection./n"
                     "This example needs SQLite support. Please read "
                     "the Qt SQL driver documentation for information how "
                     "to build it./n/n"
                     "Click Cancel to exit."), QMessageBox::Cancel);
        return false;
    }

    QSqlQuery query;
    query.exec("create table person (id int primary key, "
               "firstname varchar(20), lastname varchar(20))");
    query.exec("insert into person values(101, 'Danny', 'Young')");
    query.exec("insert into person values(102, 'Christine', 'Holand')");

    query.exec("create table images (locationid int, file varchar(20))");
    query.exec("insert into images values(0, 'images/oslo.png')");
    query.exec("insert into images values(1, 'images/brisbane.png')");

以下的操作只是往数据库中添加数据的插入操作.如果想进一步学习,请查找相当资料。


在这里我还提拱和种可以访问mysql的方法.

首先要在Qt安装好mysql的插件.

去网上下载:mingw-utils-0.3

然后将解包后在其bin目录下找到reimp.exe,拷贝到mingw的bin目录下。而且要将mingw的bin目录加到classpath下.

则可以在cmd下使用如下命令:

t> reimp -d libmysql.lib

t>dlltool -k -d libmysql.def -l libmysql.a

注意:t的目录是mysql安装目录下。我的目录为D:/MySQL/lib/opt(而且这些目录中间不能有空格,否则得不到libmysql.a

然后转到Qt的目录下(我的为D:/Qt/4.3.2/src/plugins/sqldrivers/mysql).

运行如下命令:

qmake -o Makefile "INCLUDEPATH+=D:/MySQL/lib/include" "LIBS+=D:/MySQL/lib/lib/opt/LIBMYSQL.a" mysql.pro

 

mingw32-make

这样就在D:/Qt/4.3.2/plugins/sqldrivers目录下生成libqsqlmysql4.a和qsqlmysql4.dll了.

然后就是运行一个连接到mysql数据库,测试是否成功.

QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL"); // 使用mysql数据库驱动 
db.setHostName("localhost");
db.setDatabaseName("test"); // 我们之前建立的数据库
db.setUserName("root"); // 我们创建的 yunfan 用户名
db.setPassword("123"); // yunfan 用户的密码
bool ok = db.open(); // 尝试连接数据库
if(ok) { // 这里用yunfan已经成功连上数据库
QSqlQuery query; // 新建一个查询的实例
if(query.exec("select * from t_customer")){ // 尝试列出 employee 表的所有记录
// 本次查询成功
   int numRows = 0; // 询问数据库驱动,是否驱动含有某种特性 
   if(db.driver()->hasFeature(QSqlDriver::QuerySize)){
    numRows = query.size(); // 如果支持结果影响的行数,那么直接记录下来
   } else {
    query.last(); //否则定位到结果最后,qt 文档说,这个方法非常慢
    numRows = query.at() + 1;
   }
   QString id, lname, fname, phone; 
   QDateTime dob;
   display.append("===========================================");
   display.append(QString::fromLocal8Bit(" account | password | cname | cbalance"));
   display.append("--------------------------------------");
   while(query.next()) { // 定位结果到下一条记录
    id = query.value(0).toString();
    //lname = QString::fromLocal8Bit(query.value(1).toByteArray());
    //fname = QString::fromLocal8Bit(query.value(2).toByteArray());
    //dob = query.value(3).toDateTime();
    //phone = QString::fromLocal8Bit(query.value(4).toByteArray());
    QString result = id ;//+ " " + fname + lname + " " + (dob.toString()) + " "+phone;
    display.append(result);
   }
   display.append("============================================");
   display.append(QString("totally %1 rows").arg( numRows));
} else { // 如果查询失败,用下面的方法得到具体数据库返回的原因
   QSqlError error = query.lastError();
   display.append("From mysql database: " + error.databaseText());
}
} else{ // 打开数据库失败,显示数据库返回的失败描述
display.append("cannot open database.");
display.append("Reason: " + db.lastError().databaseText());
}

如何在window下配置Qt以及IDE开发环境


在Windows配置QT环境:
1、 先安装Dev-C++。(在这个网站可下载ftp://ftp.qtopia.org.cn/mirror/dev-cpp.sourceforge.net/devcpp-4.9.9.2_setup.exe,下载后便可安装Dev-C++,假设安装目录为:C:/Dev-Cpp,其他默认安装即可)
2、 再安装Qt 4.x。(在这个网站可下载http://ftp.ntua.gr/pub/X11/Qt/qt/source/qt-win-opensource-4.3.4-mingw.exe,假设安装目录为:C:/Qt/4.3.4,在Previously installed MinGW:一项中要填入上一步中Dev-C++安装的位置 C:/Dev-Cpp,其他默认安装即可)
3、 设置PATH环境变量。(右键点击“我的电脑”->属性->高级->环境变量,在下面的用户变量里找到变量Path,点编辑,在变量值的后面加入;C:/Qt/4.3.4/bin;C:/Dev-Cpp/bin即可)
二:
编写工程文件:
main.cpp 
helloworldForm.h
 helloworldForm.ui 
helloworldForm.cpp

(其中 helloworldForm.ui 是由Qt Designer生成),其他都要手写

三:
生成项目.pro文件
C:/Qt/Project>qmake -project
生成Makefile文件
C:/Qt/Project>qmake
生成执行.exe文件
C:/Qt/Project>mingw32-make


在Qt中中文解码问题



方法一:

       #include <QApplication>
       #include <QLabel>
       #include <QTextCodec>
int main(int argc, char *argv[]) { 
       QApplication app(argc, argv);  
       QTextCodec *codec = QTextCodec::codecForName("gb18030");// Big5-ETen
       QLabel *label = new QLabel;  
       label->setText(codec->toUnicode("<center><h1>Qt4 学习笔记</h1></center>"));    
       label->setWindowTitle(codec->toUnicode("徐忠明"));   
       label->resize(200, 50);    
       label->show();    
       return app.exec();
}

即只要使用codec->toUnicode("中文");就可以实现所以中文的编码问题,但这个存在一定的缺点,就是每一次都要写上一个codec->toUnicode();能不能更简单一点的?

方法二:

QTextCodec::setCodecForTr(QTextCodec::codecForName("gb18030"));//为tr()这个做设置

这样就可以使用label->setText(tr("中文"));就可以,而且对项

目中所有的tr()都有效,不必考虑变量的域的问题

 

如:

QLabel* usrLabel = new QLabel(tr("用户名:"));

QPushButton* okBtn = new QPushButton(tr("确定"));

在Qt中实现一个对话框

主要用到三个文件.form1.h,form1.cpp,main.cpp文件

#ifndef FORM1_H_
#define FORM1_H_

---

-----------------

----------------

#endif /*FORM1_H_*/

这是宏定义是为了防止被编译多次

 

form1.h中主要是类文件的定义,包括申明一些变量和一些函数的申明

注意:Q_OBJECT,是也是一个宏,为后面该类能使用signal和slot(信号与槽)作准备。

slot(槽):

void sendMessage();
 void inputMessage();

成员变量:

QWidget *centralWidget;
  QTextCodec *codec;
  QPushButton *btnOK;
  QPushButton *btnExit;
  QPushButton *btnInput;
  QPushButton *btn;
  QVBoxLayout *layout;

 

在form1.cpp文件中:

我们实例化了构造函数和sendMessage(),inputMessage()函数

构造函数:

codec = QTextCodec::codecForName("gb18030");//中文乱码问题的解决

 centralWidget = new QWidget(this);//定义一个主框架对象

 //window->resize(250, 50);      
 this->resize(QSize(194, 323).expandedTo(this->minimumSizeHint()));//定义大小(长度和宽度)

//定义一些控件:

 btnOK = new QPushButton(codec->toUnicode("确定"),centralWidget);
 btnExit = new QPushButton(codec->toUnicode("取消"),centralWidget);
  
 //布局方式,垂直布局,上下
 QVBoxLayout *layout = new QVBoxLayout(centralWidget);
 layout->addWidget(btnOK);
 layout->addWidget(btnExit);
 layout->addWidget(btn);

 

//加载这个centralWidget到主框架居中显示

 this->setCentralWidget(centralWidget);


 setWindowTitle(codec->toUnicode("Button应用"));
 //设置标题

 

 //增加signal与slot
 QObject::connect(btnExit, SIGNAL(clicked()), this, SLOT(close()));
 QObject::connect(btn, SIGNAL(clicked()), this, SLOT(inputMessae()));
 QObject::connect(btnOK, SIGNAL(clicked()), this, SLOT(sendMessage()));

 

sendMessage部分:

// QMessageBox::warning(this, "Alert", codec->toUnicode("欢迎"), "OK");
//  QMessageBox::about(this, "About",
//              "Qt4 Gossip: <b>http://caterpillar.onlyfun.net</b>");
 
 bool isOK;

 QString text = QInputDialog::getText(this, "Input Dialog",
   "Please input your comment", QLineEdit::Normal, "your comment",&isOK);
 if (isOK) {
  QMessageBox::information(this, "Information", "Your comment is: <b>"
    + text + "</b>", QMessageBox::Yes | QMessageBox::No,QMessageBox::Yes);
 }

这里实现的功能是:通过点击一个该按钮,弹出一个对话框,以表示该点击事件被响应。

并且还可以实现特定的一些功能,如输入提示框,和一些警告信息等.

inputMessage()同理,这里就不多举止了。

纠正你的Qt编程习惯:主窗体的创建问题

先来看段代码:

#include <QApplication> #include <QWebView> #include <QUrl> int main(int argc, char* argv[]) { QApplication a(argc, argv); QWebView* mw = new QWebView; mw->show(); mw->load(QUrl("http://www.cuteqt.com/blog")); return a.exec(); }

大家看得出这段代码中的问题吗? (呵呵,不要告诉我是cuteqt不能访问哦~)

 

这段代码ms十分标准, 非常符合笔者平时写Qt程序书写main函数的习惯, 孰料想竟然是个错误的习惯,而且问题很严重哦。 给个提示:在程序退出时会aborted。

如果还没想出来是什么问题,嘿嘿,没关系,看了下面的答案你就明白了。

在这段程序里QApplication实例创建在stack上,生命期是main的大括号内, 而mw则通过new创建在heap上, 在程序退出时才会被析构。 换句话说,mw的生存期长于application的生存期…..这可是Qt编程的大忌, 因为在Qt中所有的Paint Device都必须要在有QApplication实例的情况下创建和使用。 不过如果把这个程序写出来运行一下, 未必会出现我说的aborted的问题,  大多数代码类似的程序都能安全的运行(这也是为什么用了那么多年的Qt从来没有注意过这个问题, 并且养成了我错误的编程习惯。)。  这里的trick在于application退出时mw已经被关闭, mw中的所有Paint Device一般都不会被访问到了, 所以这个错误隐藏在很深的阴暗角落, 偷偷地嘲笑我们呢!

要想试验这个问题也很简单,把load的参数换成本地文件 test.html, 并把下面的内容写进test.html就能看到拉:


-----test.html----- <form> <select id="headertest"> <option>Item1</option> <option>Item2</option> <option>Item3</option> </select> </form>

这个html里使用了下拉选单。 如果你运行程序并点开该选单,之后退出程序你就会看到Aborted错误提示,并打印出错误信息:“QWidget: Must construct a QApplication before a QPaintDevice”。

既然提出的问题,当然也要给出解决的方案。 有两种可行的方法避免该错误。 一个当然是纠正一下编程习惯,对mw不要用new的方式创建,改在stack上创建,如下代码:

#include <QApplication> #include <QWebView> #include <QUrl> int main(int arg, char* argv[]) { QApplication a(argc, argv); QWebView mw; mw.show(); mw.load(QUrl("http://www.cuteqt.com/blog")); return a.exec(); }

另外还可以用Qt提供的API解决此问题, 想办法让mw在application之前clean up, 那就是用WA_DeleteOnClose属性。 该属性标示窗体会在close时被析构, 这样就保证不会留存在application析构之后了, 是个很好的办法。

代码如下:

#include <QApplication> #include <QWebView> #include <QUrl> int main(int arg, char* argv[]) { QApplication a(argc, argv); QWebView* mw = new QWebView; mw->show(); mw->setAttribute(Qt::WA_DeleteOnClose); mw->load(QUrl("http://www.cuteqt.com/blog")); return a.exec(); }

Qt 数据库编程

现在我们讲使用数据库来进行变成,具体的提供了SELECT INSERT UPDAte DELETE等数据库的执行语句,这是在数据库的接口,当在图形下显示数据时需要使用到QSqlTableModel。所以在数据库编程之前需要掌握基础的SQL 命令语句。

  数据库驱动层

  相关联的类包含了QSqlDriver ,QSqlDriverCreatpor ,QSqlDriverCreatorBase,QSqlDriverPlugin与QSqlResult 。

  数据库的应用程序接口层

  这些类提供了访问数据库,提出一个连接请求,如同文件访问一样,当连接成功,讲通过判断信息返回信息,只要建立了连接就可以使用QSqlQuery 类来操作数据库, 在连接数据库之后还提供了几个类, 例如QSqlError ,QSqlField ,QSqlIndex 与QSqlRecord。

  用户接口层

  这些类提供了与数据相关的部件,包含了QSqlQueryModel,QSqlTableModel,与QSqlRelatiONTableModel 。这些类的定义使用是用来提供数据库的模式与试图来设计的。

  连接到数据库

  如果要建立一个数据库的连接, 首先要知道使用的什么数据库,并为这个数据库的连接加载驱动,如果是mysql 数据库,都会有用户名与密码,这也是必须设置的,被连接的数据库或许在本地或者在远程的某台计算机上,所以需要设置一个主机的名称来区别。

  下面是连接数据库的例子:

  QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");

  db.setHoSTname("bigblue");

  db.setDatabaseNAME("flightdb");

  db.setUserName("acarlson");

  db.setPassword("1uTbSbAs");

  bool k = db.open();

  我们同时也可以建立两个数据库的连接:

  QSqlDatabase firstDB = QSqlDatabase::addDatabase("QMYSQL", "first");

  QSqlDatabase secondDB = QSqlDatabase::addDatabase("QMYSQL", "second");

  在打开数据库的时候有可能会发生错误,这里提供了一个静态的函数,QSqlDatabase::lastError() 来返回当前所发生的错误。与文件相同当打开了一个数据的时候,需要在操作完毕后关闭数据库,使用QSqlDatabase::close(),之后调用QSqlDatabase::removeDatabase().

  执行数据库语句

  QSqlQuery 提供了执行数据库语句的方法,它可以返回所有的执行结果。当建立好数据库连接后可以使用QSqlQuery::exec() 如同下面的语句:

  QSqlQuery query;

  query.exec("SELECT name, salary FROM employee WHERE salary > 50000");

  当QSqlQuery 建立了一个构造之后,将会接受特定的QSqlDatabase 对象连接来使用,正如上面的代码 。

  浏览查询结果

  QSqlQuery 当执行exec() 之后将会把指针放在记录第一个记录之上,所以需要调用QSqlQuery::next()来获取第一个数据下面的代码,通过一个循环体来便利所有表中的数据:

  while (query.next()) {

  QString name = query.value(0).toString();

  int salary = query.value(1).toInt();

  qDebug() << name << salary;

  }

  QSqlQuery::value() 函数当前记录区域中的数据,作为默认的QSqlValue::value()返回的是一个QVariant类型。提供了几种可选类型的支持,他们是C++ 的基本的类型,比如int QString 与QByteArray 。对于不同类型的转换使用Qt 提供的函数来是想,例如 QVariant::toString 与QVariant::toInt() 。

从今天开始我们学习Qt数据库编程的内容。
先说明:我们以后使用现在最新的基于Qt 4.6.2的Qt Creator 1.3.1 Windows版本,该版本是2010年2月17日发布的。
数据库几乎是每个较大的软件所必须应用的,而在Qt中也使用QtSql模块实现了对数据库的完美支持。我们在Qt Creator的帮助中查找QtSql Module,其内容如下图:

可以看到这个模块是一组类的集合,使用这个模块我们需要加入头文件#include <QtSql>,而在工程文件中需要加入一行代码:QT += sql
这里每个类的作用在后面都有简单的介绍,你也可以进入其中查看其详细内容。下面我们先简单的说一下QSqlDatabase类和QSqlQuery类。
QSqlDatabase类实现了数据库连接的操作,现在Qt支持的数据库类型有如下几种:

而现在我们使用的免费的Qt只提供了SQLite和ODBC数据库的驱动(我们可以在Qt Creator安装目录下的qt\plugins\sqldrivers文件夹下查看),而其他数据库的驱动需要我们自己添加。SQLite是一个小巧的 嵌入式数据库,关于它的介绍你可以自己在网上查找。
QSqlQuery类用来执行SQL语句。(关于SQL语句:在我的教程中只会出现很简单的SQL语句,你没有相关知识也可以看懂,但是如果想进行深入学习,就需要自己学习相关知识了。)
下面我们就先利用这两个类来实现最简单的数据库程序,其他的类我们会在以后的教程中逐个学习到。
1.新建Qt控制台工程。

2.选择上QtSql模块,这样就会自动往工程文件中添加QT += sql 这行代码了。

3.修改main.cpp中的内容如下。
#include <QtCore/QCoreApplication>
#include <QtSql>
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QSqlDatabase db = QSqlDatabase::addDatabase(“QSQLITE”); //添加数据库驱动
    db.setDatabaseName(“:memory:”); //数据库连接命名
    if(!db.open()) //打开数据库
    {
        return false;
    }

    QSqlQuery query; //以下执行相关QSL语句
    query.exec(“create table student(id int primary key,name varchar)”);
    //新建student表,id设置为主键,还有一个name项
    query.exec(“insert into student values(1,’xiaogang’)”);
    query.exec(“insert into student values(2,’xiaoming’)”);
    query.exec(“insert into student values(3,’xiaohong’)”);
    
//向表中插入3条记录
    query.exec(“select id,name from student where id >= 2″);
    //查找表中id >=2 的记录的id项和name项的值
    while(query.next())       //query.next()指向查找到的第一条记录,然后每次后移一条记录
    {
        int ele0 = query.value(0).toInt();       //query.value(0)是id的值,将其转换为int型
        QString ele1 =query.value(1).toString();
        qDebug() << ele0 <<ele1 ;       //输出两个值
    }
   
    return a.exec();
}
我们使用了SQLite数据库,连接名为“:memory:”表示这是建立在内存中的数据库,也就是说该数据库只在程序运行期间有效。如果需要保存该数据库文件,我们可以将它更改为实际的文件路径。
4.最终效果如下。

5.我们可以将主函数更改如下。
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    qDebug() << “Available drivers:”;
    QStringList drivers = QSqlDatabase::drivers();
    foreach(QString driver, drivers)
    qDebug() << “\t” << driver;

    return a.exec();
}
这样运行程序就可以显示现在所有能用的数据库驱动了。

可以看到现在可用的数据库驱动只有三个。

  QModelIndex *rmi = new QModelIndex;

    QString roomid,buildid;

    *rmi = ui->tableView->model()->index(ui->tableView->currentIndex().row(),0);

    buildid = rmi->data().toString();

    *rmi = ui->tableView->model()->index(ui->tableView->currentIndex().row(),1);

    roomid = rmi->data().toString();


  评论这张
 
阅读(1941)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017