天天看點

[Qt教程] 第24篇 資料庫(四)SQL查詢模型QSqlQueryModel [Qt教程] 第24篇 資料庫(四)SQL查詢模型QSqlQueryModel

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

[Qt教程] 第24篇 資料庫(四)SQL查詢模型QSqlQueryModel [Qt教程] 第24篇 資料庫(四)SQL查詢模型QSqlQueryModel

 發表于 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 &lt;qsqldatabase&gt;

#include &lt;qsqlquery&gt;

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 &lt;qapplication&gt;

#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-&gt;setquery("select

* from student");

    model-&gt;setheaderdata(0, qt::horizontal, tr("id"));

    model-&gt;setheaderdata(1, qt::horizontal, tr("name"));

    qtableview *view = new qtableview;

    view-&gt;setmodel(model);

    view-&gt;show();

這裡建立了qsqlquerymodel類對象model,并用setquery()函數執行了sql語句“("select * fromstudent");”用來查詢整個student表的内容,可以看到,該類并沒有完全避免sql語句。然後我們設定了表中屬性顯示時的名字。最後我們建立了一個視圖view,并将這個model模型關聯到視圖中,這樣資料庫中的資料就能在視窗上的表中顯示出來了。

6.在mainwindow.cpp中添加頭檔案包含:

#include &lt;qsqlquerymodel&gt;

#include &lt;qtableview&gt;

7.運作程式,按下查詢按鈕,效果如下圖所示。

[Qt教程] 第24篇 資料庫(四)SQL查詢模型QSqlQueryModel [Qt教程] 第24篇 資料庫(四)SQL查詢模型QSqlQueryModel

8.我們檢視一下編譯生成的目錄(我這裡是e:\querymodel-build-桌面-debug),這裡面有生成的資料庫檔案,如下圖所示。

[Qt教程] 第24篇 資料庫(四)SQL查詢模型QSqlQueryModel [Qt教程] 第24篇 資料庫(四)SQL查詢模型QSqlQueryModel

1.在查詢按鈕槽中繼續添加如下代碼:

int column=

model-&gt;columncount(); //獲得列數

int row

= model-&gt;rowcount();    // 獲得行數

qsqlrecord record

= model-&gt;record(1); //獲得一條記錄

qmodelindex index

= model-&gt;index(1,1);   //獲得一條記錄的一個屬性的值

qdebug() &lt;&lt; "column numis:" &lt;&lt; column &lt;&lt; endl

        &lt;&lt; "row

num is:" &lt;&lt; row

&lt;&lt; endl

        &lt;&lt;"the

second record is:" &lt;&lt; record

        &lt;&lt; "the

data of index(1,1) is:"&lt;&lt; index.data();

2.然後在mainwindow.cpp檔案中添加下面的頭檔案包含:

#include &lt;qsqlrecord&gt;

#include &lt;qmodelindex&gt;

#include &lt;qdebug&gt;

3.運作程式,點選查詢按鈕,輸出内容如下圖所示。

[Qt教程] 第24篇 資料庫(四)SQL查詢模型QSqlQueryModel [Qt教程] 第24篇 資料庫(四)SQL查詢模型QSqlQueryModel

4.另外我們可以直接使用上一節講到的qsqlquery來執行sql語句,例如:

qsqlquery query

= model-&gt;query();

query.exec("select name from studentwhere id = 2 ");

query.next();

qdebug() &lt;&lt; query.value(0).tostring();

5.我們将查詢按鈕槽更改如下:

    qsqlquery query = model-&gt;query();

    query.exec("insertinto

student values (10,'yafei10')");

       這裡使用query向表中添加了一條記錄。

6.在mainwindow.cpp中添加頭檔案#include &lt;qsqlquery&gt;,然後運作程式,發現最後添加的記錄并沒有顯示出來,當關閉程式,再次運作的時候才顯示出來,效果如下圖所示。

[Qt教程] 第24篇 資料庫(四)SQL查詢模型QSqlQueryModel [Qt教程] 第24篇 資料庫(四)SQL查詢模型QSqlQueryModel

7.為什麼會出現上面的情況呢?那是因為前面我們執行了添加記錄的sql語句,但是在添加記錄之前,查詢結果就已經顯示了,是以我們的更新沒能動态的顯示出來。為了能讓其動态地顯示我們的更新,可以将槽最後的代碼更改如下:

qsqlquery query = model-&gt;query();

query.exec("insert

into student values (20,'yafei20')");

model-&gt;setquery("select

* from student"); //再次查詢整張表

view-&gt;show(); //再次進行顯示

       這裡我們修改完表以後,再次進行了查詢并顯示。大家可以運作程式,發現新的記錄可以直接顯示出來了。

       前面我們講到這個模型預設是隻讀的,是以在視窗上并不能對表格中的内容進行修改。但是我們可以建立自己的模型,然後按照自己的意願來顯示資料和修改資料。要想使其可讀寫,需要自己的類繼承自qsqlquerymodel,并且重寫setdata() 和 flags() 兩個函數。如果我們要改變資料的顯示,就要重寫data() 函數。

       下面的例子中我們讓student表查詢結果的id屬性列顯示紅色,name屬性列可編輯。

1.向項目中添加新的c++類,類名為mysqlquerymodel,基類為qsqlquerymodel,類型資訊選擇“繼承自qobject”。

2.完成後打開mysqlquerymodel.h檔案,在public中添加函數聲明:

qt::itemflags flags(const qmodelindex &amp;index)

const;

bool setdata(const qmodelindex &amp;index,

const qvariant &amp;value, int role);

qvariant data(const qmodelindex &amp;item,

int role=qt::displayrole) const;

然後添加私有函數聲明:

private:

    bool setname(int studentid,

const qstring &amp;name);

    void refresh();

3.到mysqlquerymodel.cpp檔案中,更改如下:

#include "mysqlquerymodel.h"

#include &lt;qcolor&gt;

mysqlquerymodel::mysqlquerymodel(qobject *parent) :

    qsqlquerymodel(parent)

qt::itemflags mysqlquerymodel::flags(

       const qmodelindex &amp;index) const //傳回表格是否可更改的标志

    qt::itemflags flags = qsqlquerymodel::flags(index);

    if (index.column() == 1) //第二個屬性可更改

       flags |= qt::itemiseditable;

    return flags;

bool mysqlquerymodel::setdata(const qmodelindex &amp;index, const qvariant &amp;value, int /*

role */)

       //添加資料

    if (index.column() &lt; 1 || index.column() &gt; 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 &amp;name)

    query.prepare("update

student set name = ? where id = ?");

    query.addbindvalue(name);

    query.addbindvalue(studentid);

    return query.exec();

//更改資料顯示樣式

qvariant mysqlquerymodel::data(const qmodelindex &amp;index, int role) const

qvariant value = qsqlquerymodel::data(index, role);

//第一個屬性的字型顔色為紅色

    if (role == qt::textcolorrole &amp;&amp; index.column() == 0)

       return qvariantfromvalue(qcolor(qt::red)); 

return value;

4.到mainwindow.cpp檔案中先添加頭檔案包含:

5.更改查詢按鈕槽内容如下:

//建立自己模型的對象

    mysqlquerymodel *mymodel = new mysqlquerymodel;    mymodel-&gt;setquery("select * from student");

    mymodel-&gt;setheaderdata(0, qt::horizontal, tr("id"));

    mymodel-&gt;setheaderdata(1, qt::horizontal, tr("name"));

    qtableview *view1 = new qtableview;

    view1-&gt;setwindowtitle("mysqlquerymodel"); //修改視窗标題

    view1-&gt;setmodel(mymodel);

    view1-&gt;show();

運作程式,效果如下圖所示。

[Qt教程] 第24篇 資料庫(四)SQL查詢模型QSqlQueryModel [Qt教程] 第24篇 資料庫(四)SQL查詢模型QSqlQueryModel

結語

       本節講解了qsqlquerymodel的相關内容,該類預設是一個隻讀的sql語句查詢模型,不過可以對其進行重寫來實作編輯功能。下一節我們将講解封裝更好的qsqltablemodel模型,它已經基本上擺脫了sql語句。

涉及到的源碼: 

[Qt教程] 第24篇 資料庫(四)SQL查詢模型QSqlQueryModel [Qt教程] 第24篇 資料庫(四)SQL查詢模型QSqlQueryModel

kb, 下載下傳次數: 7)