<a target="_blank" href="http://bbs.qter.org/forum.php?mod=viewthread&tid=183">樓主</a>

發表于 2013-5-21 14:33:47 | 檢視:
869| 回複: 1
sql查詢模型qsqlquerymodel
版權聲明
該文章原創于作者yafeilinux,轉載請注明出處!
導語
在上一篇的最後我們講到,qt中使用了自己的機制來避免使用sql語句,為我們提供了更簡單的資料庫操作及資料顯示模型,分别是隻讀的qsqlquerymodel,操作單表的qsqltablemodel和以及可以支援外鍵的qsqlrelationaltablemodel。這次我們先講解qsqlquerymodel。
環境:windows xp + qt 4.8.4+qt creator2.6.2
目錄
一、簡單的查詢操作
二、qsqlquerymodel常用操作
三、建立自定義qsqlquerymodel
正文
1.建立qt gui應用,項目名稱為querymodel,基類為qmainwindow,類名為mainwindow。
2.完成後打開querymodel.pro,将第一行代碼更改為:
qt += core gui sql
然後儲存該檔案。
3.往項目中添加新的c++頭檔案,名稱為connection.h,完成後将其内容更改如下:
#ifndef connection_h
#define connection_h
#include <qsqldatabase>
#include <qsqlquery>
static bool createconnection()
{
qsqldatabase db = qsqldatabase::adddatabase("qsqlite");
db.setdatabasename("database.db");
if(!db.open()) return false;
qsqlquery query;
query.exec("create
table student (id int primary key, namevchar)");
query.exec("insert
into student values (0,'yafei0')");
into student values (1,'yafei1')");
into student values (2,'yafei2')");
return true;
}
#endif //
connection_h
這裡使用了db.setdatabasename("database.db");,我們沒有再使用以前的記憶體資料庫,而是使用了真實的檔案,這樣後面對資料庫進行的操作就能儲存下來了。
4.然後進入main.cpp檔案,更改如下:
#include "mainwindow.h"
#include <qapplication>
#include "connection.h"
int main(int argc, char *argv[])
{
qapplication a(argc, argv);
if(!createconnection())
return 1;
mainwindow w;
w.show();
return a.exec();
5.下面進入設計模式,向界面上拖入一個push button按鈕,更改顯示文本為“查詢”,然後進入其單擊信号槽,更改如下:
void mainwindow::on_pushbutton_clicked()
qsqlquerymodel *model = new qsqlquerymodel;
model->setquery("select
* from student");
model->setheaderdata(0, qt::horizontal, tr("id"));
model->setheaderdata(1, qt::horizontal, tr("name"));
qtableview *view = new qtableview;
view->setmodel(model);
view->show();
這裡建立了qsqlquerymodel類對象model,并用setquery()函數執行了sql語句“("select * fromstudent");”用來查詢整個student表的内容,可以看到,該類并沒有完全避免sql語句。然後我們設定了表中屬性顯示時的名字。最後我們建立了一個視圖view,并将這個model模型關聯到視圖中,這樣資料庫中的資料就能在視窗上的表中顯示出來了。
6.在mainwindow.cpp中添加頭檔案包含:
#include <qsqlquerymodel>
#include <qtableview>
7.運作程式,按下查詢按鈕,效果如下圖所示。
8.我們檢視一下編譯生成的目錄(我這裡是e:\querymodel-build-桌面-debug),這裡面有生成的資料庫檔案,如下圖所示。
1.在查詢按鈕槽中繼續添加如下代碼:
int column=
model->columncount(); //獲得列數
int row
= model->rowcount(); // 獲得行數
qsqlrecord record
= model->record(1); //獲得一條記錄
qmodelindex index
= model->index(1,1); //獲得一條記錄的一個屬性的值
qdebug() << "column numis:" << column << endl
<< "row
num is:" << row
<< endl
<<"the
second record is:" << record
<< "the
data of index(1,1) is:"<< index.data();
2.然後在mainwindow.cpp檔案中添加下面的頭檔案包含:
#include <qsqlrecord>
#include <qmodelindex>
#include <qdebug>
3.運作程式,點選查詢按鈕,輸出内容如下圖所示。
4.另外我們可以直接使用上一節講到的qsqlquery來執行sql語句,例如:
qsqlquery query
= model->query();
query.exec("select name from studentwhere id = 2 ");
query.next();
qdebug() << query.value(0).tostring();
5.我們将查詢按鈕槽更改如下:
qsqlquery query = model->query();
query.exec("insertinto
student values (10,'yafei10')");
這裡使用query向表中添加了一條記錄。
6.在mainwindow.cpp中添加頭檔案#include <qsqlquery>,然後運作程式,發現最後添加的記錄并沒有顯示出來,當關閉程式,再次運作的時候才顯示出來,效果如下圖所示。
7.為什麼會出現上面的情況呢?那是因為前面我們執行了添加記錄的sql語句,但是在添加記錄之前,查詢結果就已經顯示了,是以我們的更新沒能動态的顯示出來。為了能讓其動态地顯示我們的更新,可以将槽最後的代碼更改如下:
qsqlquery query = model->query();
query.exec("insert
into student values (20,'yafei20')");
model->setquery("select
* from student"); //再次查詢整張表
view->show(); //再次進行顯示
這裡我們修改完表以後,再次進行了查詢并顯示。大家可以運作程式,發現新的記錄可以直接顯示出來了。
前面我們講到這個模型預設是隻讀的,是以在視窗上并不能對表格中的内容進行修改。但是我們可以建立自己的模型,然後按照自己的意願來顯示資料和修改資料。要想使其可讀寫,需要自己的類繼承自qsqlquerymodel,并且重寫setdata() 和 flags() 兩個函數。如果我們要改變資料的顯示,就要重寫data() 函數。
下面的例子中我們讓student表查詢結果的id屬性列顯示紅色,name屬性列可編輯。
1.向項目中添加新的c++類,類名為mysqlquerymodel,基類為qsqlquerymodel,類型資訊選擇“繼承自qobject”。
2.完成後打開mysqlquerymodel.h檔案,在public中添加函數聲明:
qt::itemflags flags(const qmodelindex &index)
const;
bool setdata(const qmodelindex &index,
const qvariant &value, int role);
qvariant data(const qmodelindex &item,
int role=qt::displayrole) const;
然後添加私有函數聲明:
private:
bool setname(int studentid,
const qstring &name);
void refresh();
3.到mysqlquerymodel.cpp檔案中,更改如下:
#include "mysqlquerymodel.h"
#include <qcolor>
mysqlquerymodel::mysqlquerymodel(qobject *parent) :
qsqlquerymodel(parent)
qt::itemflags mysqlquerymodel::flags(
const qmodelindex &index) const //傳回表格是否可更改的标志
qt::itemflags flags = qsqlquerymodel::flags(index);
if (index.column() == 1) //第二個屬性可更改
flags |= qt::itemiseditable;
return flags;
bool mysqlquerymodel::setdata(const qmodelindex &index, const qvariant &value, int /*
role */)
//添加資料
if (index.column() < 1 || index.column() > 2)
return false;
qmodelindex primarykeyindex = qsqlquerymodel::index(index.row(),
0);
int id = data(primarykeyindex).toint(); //擷取id号
clear();
bool ok;
ok = setname(id, value.tostring());
refresh();
return ok;
void mysqlquerymodel::refresh() //更新顯示
setquery("select
setheaderdata(0, qt::horizontal, qobject::tr("id"));
setheaderdata(1, qt::horizontal, qobject::tr("name"));
//添加name屬性的值
bool mysqlquerymodel::setname(int studentid, const qstring &name)
query.prepare("update
student set name = ? where id = ?");
query.addbindvalue(name);
query.addbindvalue(studentid);
return query.exec();
//更改資料顯示樣式
qvariant mysqlquerymodel::data(const qmodelindex &index, int role) const
qvariant value = qsqlquerymodel::data(index, role);
//第一個屬性的字型顔色為紅色
if (role == qt::textcolorrole && index.column() == 0)
return qvariantfromvalue(qcolor(qt::red));
return value;
4.到mainwindow.cpp檔案中先添加頭檔案包含:
5.更改查詢按鈕槽内容如下:
//建立自己模型的對象
mysqlquerymodel *mymodel = new mysqlquerymodel; mymodel->setquery("select * from student");
mymodel->setheaderdata(0, qt::horizontal, tr("id"));
mymodel->setheaderdata(1, qt::horizontal, tr("name"));
qtableview *view1 = new qtableview;
view1->setwindowtitle("mysqlquerymodel"); //修改視窗标題
view1->setmodel(mymodel);
view1->show();
運作程式,效果如下圖所示。
結語
本節講解了qsqlquerymodel的相關内容,該類預設是一個隻讀的sql語句查詢模型,不過可以對其進行重寫來實作編輯功能。下一節我們将講解封裝更好的qsqltablemodel模型,它已經基本上擺脫了sql語句。
涉及到的源碼:
kb, 下載下傳次數: 7)