Qt資料庫(五)QSqlQueryModel

來源:互聯網
上載者:User

本文章原創於www.yafeilinux.com 轉載請註明出處。

在上一篇的最後我們說到,Qt中使用了自己的機制來避免使用SQL語句,它為我們提供了更簡單的資料庫操作和資料顯示模型。它們分別是唯讀QSqlQueryModel,操作單表的QSqlTableModel和以及可以支援外鍵的QSqlRelationalTableModel。這次我們先講解QSqlQueryModel。

QSqlQueryModel類為SQL的結果集提供了一個唯讀資料模型,下面我們先利用這個類進行一個最簡單的操作。

我們建立Qt4 Gui Application工程,我這裡工程名為queryModel ,然後選中QtSql模組,Base class選QWidget。工程建好後,添加C++ Header File ,命名為database.h,更改其內容如下:

#ifndef DATABASE_H
#define DATABASE_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, name vchar)”);
    query.exec(“insert into student values (0,’yafei0′)”);
    query.exec(“insert into student values (1,’yafei1′)”);
    query.exec(“insert into student values (2,’yafei2′)”);
    return true;
}

#endif // DATABASE_H

這裡我們使用了db.setDatabaseName(“database.db”); ,我們沒有再使用以前的記憶體資料庫,而是使用了真實的檔案,這樣後面對資料庫進行的操作就能儲存下來了。

然後進入main.cpp,將其內容更改如下:

#include <QtGui/QApplication>
#include “widget.h”
#include “database.h”
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    if(!createConnection())
        return 1;
    Widget w;
    w.show();
    return a.exec();
}

下面我們在widget.ui中添加一個顯示為“查詢”的Push Button,並進入其單擊事件槽函數,更改如下:

void Widget::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 * from student”);”用來查詢整個student表的內容,可以看到,該類並沒有完全避免SQL語句。然後我們設定了表中屬性顯示時的名字。最後我們建立了一個視圖view,並將這個model模型關聯到視圖中,這樣資料庫中的資料就能在視窗上的表中顯示出來了。

我們在widget.cpp中添加標頭檔:

#include <QSqlQueryModel>
#include <QTableView>

我們運行程式,並按下“查詢”按鍵,效果如下:

我們在工程檔案夾下查看資料庫檔案:



下面我們利用這個模型來操作資料庫。

1.我們在void Widget::on_pushButton_clicked()函數中添加如下代碼:

int column = model->columnCount(); //獲得列數
int row = model->rowCount();    // 獲得行數
QSqlRecord record = model->record(1); //獲得一條記錄
QModelIndex index = model->index(1,1);   //獲得一條記錄的一個屬性的值
qDebug() << “column num is:” << column << endl
            << “row num is:” << row << endl
            <<”the second record is:” << record << endl
            << “the data of index(1,1) is:”<< index.data();

在我們在widget.cpp中添加標頭檔:

#include <QSqlRecord>
#include <QModelIndex>
#include <QDebug>

此時運行程式,效果如下:


2.當然我們在這裡也可以使用前面介紹過的query執行SQL語句。

例如我們在void Widget::on_pushButton_clicked()函數中添加如下代碼:

QSqlQuery query = model->query();
query.exec(“select name from student where id = 2 “);
query.next();
qDebug() << query.value(0).toString();

這樣就可以輸出表中的值了,你可以運行程式測試一下。

3.當我們將函數改為如下。

void Widget::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();

    QSqlQuery query = model->query();
    query.exec(“insert into student values (10,’yafei10′)”);
    //插入一條記錄
}

這時我們運行程式,效果如下:

我們發現表格中並沒有增加記錄,怎麼回事呢?

我們關閉程式,再次運行,效果如下:

發現這次新的記錄已經添加了。在上面我們執行了添加記錄的SQL語句,但是在添加記錄之前,就已經進行顯示了,所以我們的更新沒能動態顯示出來。為了能讓其動態地顯示我們的更新,我們可以將函數更改如下:

void Widget::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();

    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++ Class,然後Class name設為MySqlQueryModel,Base Class設為QSqlQueryModel,如下:


2.我們將mysqlquerymodel.h中的內容更改如下:

class MySqlQueryModel : public QSqlQueryModel
{
public:
    MySqlQueryModel();
    //下面三個函數都是虛函數,我們對其進行重載
    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();
};

然後將mysqlquerymodel.cpp檔案更改如下:

#include “mysqlquerymodel.h”
#include <QSqlQuery>
#include <QColor>

MySqlQueryModel::MySqlQueryModel()
{
}

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;
    if (index.column() == 1) //第二個屬性可更改
        ok = setName(id, value.toString());

    refresh();
    return ok;
}

void MySqlQueryModel::refresh() //更新顯示
{
    setQuery(“select * from student”);
    setHeaderData(0, Qt::Horizontal, QObject::tr(“id”));
    setHeaderData(1, Qt::Horizontal, QObject::tr(“name”));
}

bool MySqlQueryModel::setName(int studentId, const QString &name) //添加name屬性的值
{
    QSqlQuery query;
    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;
}

在widget.cpp檔案中添加標頭檔:#include “mysqlquerymodel.h”

然後更改函數如下:

void Widget::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();

    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();
}

運行效果如下:


可以看到我們要的效果已經出來了。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.