欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Qt實現(xiàn)SqlRelationalTable關(guān)聯(lián)表組件

 更新時間:2023年12月29日 16:11:51   作者:微軟技術(shù)分享  
在Qt中我們可以通過拖拽的方式將不同組件放到指定的位置,實現(xiàn)圖形化開發(fā)極大的方便了開發(fā)效率,本章將重點介紹SqlRelationalTable關(guān)聯(lián)表組件的常用方法及靈活運用,感興趣的可以了解一下

Qt 是一個跨平臺C++圖形界面開發(fā)庫,利用Qt可以快速開發(fā)跨平臺窗體應(yīng)用程序,在Qt中我們可以通過拖拽的方式將不同組件放到指定的位置,實現(xiàn)圖形化開發(fā)極大的方便了開發(fā)效率,本章將重點介紹SqlRelationalTable關(guān)聯(lián)表組件的常用方法及靈活運用。

在上一篇文章中詳細介紹了SqlTableModle組件是如何使用的,本篇文章將介紹SqlRelationalTable關(guān)聯(lián)表組件,該該組件其實是SqlTableModle組件的擴展類,其提供了一個帶關(guān)系的數(shù)據(jù)模型,用于處理數(shù)據(jù)庫中的表與表之間的關(guān)系。通過這個類,你可以在一個表中使用外鍵關(guān)聯(lián)到另一個表的數(shù)據(jù)上。例如將主表中的某個字段與附加表中的特定字段相關(guān)聯(lián)起來,QSqlRelation(關(guān)聯(lián)表名,關(guān)聯(lián)ID,名稱)就是用來實現(xiàn)多表之間快速關(guān)聯(lián)的。

1.1 ComboBox

首先我們來實現(xiàn)一個簡單的聯(lián)動效果,數(shù)據(jù)庫組件可以與ComboBox組件形成多級聯(lián)動效果,在日常開發(fā)中多級聯(lián)動效果應(yīng)用非常廣泛,例如當我們選擇指定用戶時,讓其在另一個ComboBox組件中列舉出該用戶所維護的主機列表,又或者當用戶選擇省份時,自動列舉出該省份下面的城市列表等。

在進行聯(lián)動之前需要創(chuàng)建兩張表,表結(jié)構(gòu)內(nèi)容介紹如下:

  • User(id,name)表:存儲指定用戶的ID號與用戶名
  • UserAddressList(id,name,address)表:與User表中的用戶名相關(guān)聯(lián),存儲該用戶所管理的主機列表信息

通過數(shù)據(jù)庫組件實現(xiàn)的聯(lián)動非常簡單,初始化表結(jié)構(gòu)得到了兩張表,當程序運行時默認在MainWindow構(gòu)造函數(shù)處填充第一個ComboBox組件,也就是執(zhí)行一次數(shù)據(jù)庫查詢,并將結(jié)果通過addItem()放入到第一個組件內(nèi)。

QSqlDatabase db;

MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    InitMultipleSQL();

    db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName("./database.db");
     if (!db.open())
     {
            std::cout << db.lastError().text().toStdString()<< std::endl;
            return;
     }

     QSqlQuery query;
     query.exec("select * from User;");
     QSqlRecord rec = query.record();

     while(query.next())
     {
         int index_name = rec.indexOf("name");
         QString data_name = query.value(index_name).toString();
         ui->comboBox_user->addItem(data_name);
     }
}

而當用戶選中了第一個ComboBox組件時,則讓其轉(zhuǎn)到槽函數(shù)on_comboBox_activated(const QString &arg1)上面,如下圖所示;

該槽函數(shù)需要一個傳入?yún)?shù),此參數(shù)代表組件選中的文本內(nèi)容,通過利用該文本內(nèi)容在數(shù)據(jù)庫內(nèi)執(zhí)行二次查詢并將查詢結(jié)果填充之對應(yīng)的第二個ComboBox組件內(nèi)即可實現(xiàn)組件的聯(lián)動選擇效果,其槽函數(shù)代碼如下所示;

void MainWindow::on_comboBox_user_activated(const QString &arg1)
{
    if(db.open())
    {
        QSqlQuery query;
        query.prepare("select * from UserAddressList where name = :x");
        query.bindValue(":x",arg1);
        query.exec();

        QSqlRecord rec = query.record();

        ui->comboBox_address->clear();
        while(query.next())
        {
            int index = rec.indexOf("address");
            QString data_ = query.value(index).toString();
            ui->comboBox_address->addItem(data_);
        }
    }
}

讀者可自行運行案例中的SqlComboBox案例,運行后可自行選擇不同的用戶名,則此時會輸出該用戶名所對應(yīng)的地址表,如下圖所示;

1.2 TableView

接著,我們繼續(xù)以TableView組件為例,簡單介紹一下如何實現(xiàn)組件與數(shù)據(jù)的綁定,首先我們需要創(chuàng)建一個表并插入幾條測試記錄,運行如下代碼實現(xiàn)建庫建表.

創(chuàng)建一張新表,表結(jié)構(gòu)內(nèi)容介紹如下:

  • LyShark(name,age)表:存儲指定用戶名與用戶年齡

在主構(gòu)造函數(shù)中我們可以直接通過QSqlQueryModel來得到特定表中的記錄,并通過setHeaderData將表中的數(shù)據(jù)關(guān)聯(lián)到對應(yīng)的數(shù)據(jù)模型內(nèi),最后通過setModel方法即可將對應(yīng)的表數(shù)據(jù)關(guān)聯(lián)到前端顯示,其核心代碼如下所示;

MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    Init();

    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName("./database.db");
     if (!db.open())
     {
            std::cout << db.lastError().text().toStdString()<< std::endl;
            return;
     }

     // 查詢數(shù)據(jù)表中記錄
     qryModel=new QSqlQueryModel(this);
     qryModel->setQuery("SELECT * FROM LyShark ORDER BY id");
     if (qryModel->lastError().isValid())
     {
         return;
     }

     // 設(shè)置TableView表頭數(shù)據(jù)
     qryModel->setHeaderData(0,Qt::Horizontal,"ID");
     qryModel->setHeaderData(1,Qt::Horizontal,"Name");
     qryModel->setHeaderData(2,Qt::Horizontal,"Age");

     // 將數(shù)據(jù)綁定到模型上
     theSelection=new QItemSelectionModel(qryModel);
     ui->tableView->setModel(qryModel);
     ui->tableView->setSelectionModel(theSelection);
     ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
}

運行代碼后,程序會從數(shù)據(jù)庫內(nèi)取出結(jié)果并輸出到tableView組件上,如下圖所示;

1.3 SqlRelationalTable

在最開始我們也說過,SqlRelationalTable 并不是Qt中標準的類或方法。它僅僅只是QSqlTableModel的一個子類,其支持在關(guān)系數(shù)據(jù)庫表之間建立關(guān)系,建立關(guān)聯(lián)時我們只需要使用setRelation方法即可。

setRelation 是 QSqlRelationalTableModel 類中的一個方法,用于設(shè)置模型中某一列的關(guān)聯(lián)關(guān)系。這個方法的目的是告訴模型某一列的值在另一個表中有關(guān)聯(lián),并提供相關(guān)的信息,以便在視圖中顯示更有意義的數(shù)據(jù)而不是外鍵的原始值。

以下是 setRelation 方法的簡單說明:

void QSqlRelationalTableModel::setRelation(int column, const QSqlRelation &relation);
  • column: 要設(shè)置關(guān)聯(lián)關(guān)系的列的索引。
  • relation: 包含關(guān)聯(lián)信息的 QSqlRelation 對象。

QSqlRelation 的構(gòu)造函數(shù)如下:

QSqlRelation::QSqlRelation(const QString &tableName, const QString &indexColumn, const QString &displayColumn);
  • tableName: 關(guān)聯(lián)的表的名稱。
  • indexColumn: 關(guān)聯(lián)表中與當前表關(guān)聯(lián)的列的名稱,通常是外鍵列。
  • displayColumn: 關(guān)聯(lián)表中要顯示的列的名稱,通常是與外鍵列相關(guān)的實際數(shù)據(jù)。

示例:

QSqlRelationalTableModel model;
model.setTable("orders");
model.setRelation(2, QSqlRelation("customers", "customer_id", "customer_name"));
model.select();

在這個例子中,第二列(索引為2的列)的數(shù)據(jù)將從名為 “customers” 的表中獲取,該表的外鍵列為 “customer_id”,并且在視圖中顯示的是該關(guān)聯(lián)表的 “customer_name” 列的值。使用 setRelation 方法可以使得在表格中更容易地顯示和編輯關(guān)聯(lián)數(shù)據(jù),而不是直接顯示外鍵的值。

在關(guān)聯(lián)表之前,我們需要設(shè)置初始化數(shù)據(jù),此處我們提供兩個表結(jié)構(gòu),表Student用于存儲學(xué)生名字以及學(xué)生課程號,另一張Departments則用于存儲每個編號所對應(yīng)的系名稱,運行代碼完成創(chuàng)建。

// 初始化數(shù)據(jù)表
void MainWindow::InitSQL()
{
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName("./database.db");
    if (!db.open())
           return;

    // 執(zhí)行SQL創(chuàng)建表
    db.exec("DROP TABLE Student");
    db.exec("CREATE TABLE Student ("
                   "id INTEGER PRIMARY KEY AUTOINCREMENT, "
                   "name VARCHAR(40) NOT NULL, "
                   "departID INTEGER NOT NULL)"
            );

    // 逐條插入數(shù)據(jù)
    db.exec("INSERT INTO Student(name,departID) VALUES('zhangsan',10)");
    db.exec("INSERT INTO Student(name,departID) VALUES('lisi',20)");
    db.exec("INSERT INTO Student(name,departID) VALUES('wangwu',30)");
    db.exec("INSERT INTO Student(name,departID) VALUES('wangmazi',40)");

    db.exec("DROP TABLE Departments");
    db.exec("CREATE TABLE Departments("
            "departID INTEGER NOT NULL,"
            "department VARCHAR(40) NOT NULL)"
            );

    db.exec("INSERT INTO Departments(departID,department) VALUES (10,'數(shù)學(xué)學(xué)院')");
    db.exec("INSERT INTO Departments(departID,department) VALUES (20,'物理學(xué)院')");
    db.exec("INSERT INTO Departments(departID,department) VALUES (30,'計算機學(xué)院')");
}

接著我們來看下在MainWindow構(gòu)造函數(shù)中是如何進行初始化和表關(guān)聯(lián)的,以下是對代碼的簡要說明:

打開數(shù)據(jù)庫連接

創(chuàng)建一個 SQLite 數(shù)據(jù)庫連接,并指定了數(shù)據(jù)庫文件的路徑。如果數(shù)據(jù)庫連接成功打開,就繼續(xù)執(zhí)行后面的代碼。

QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("./database.db");
if (!db.open())
    return;

設(shè)置主窗口的布局和屬性

將主窗口的中央部件設(shè)置為一個 QTableView,同時對表格的選擇行為和外觀進行了設(shè)置。

this->setCentralWidget(ui->tableView);
ui->tableView->setSelectionBehavior(QAbstractItemView::SelectItems);
ui->tableView->setSelectionMode(QAbstractItemView::SingleSelection);
ui->tableView->setAlternatingRowColors(true);

打開數(shù)據(jù)表并設(shè)置模型

創(chuàng)建一個 QSqlRelationalTableModel 并設(shè)置了一些表格的屬性,包括表名、編輯策略、排序等。

tabModel = new QSqlRelationalTableModel(this, db);
tabModel->setTable("Student");
tabModel->setEditStrategy(QSqlTableModel::OnManualSubmit);
tabModel->setSort(0, Qt::AscendingOrder);

tabModel->setHeaderData(0, Qt::Horizontal, "學(xué)號");
tabModel->setHeaderData(1, Qt::Horizontal, "姓名");
tabModel->setHeaderData(2, Qt::Horizontal, "學(xué)院");

設(shè)置查詢關(guān)系數(shù)據(jù)表

設(shè)置關(guān)系型字段,將 “學(xué)院” 列與 “Departments” 表中的 “departID” 列關(guān)聯(lián)起來,并在表格中顯示 “department” 列的數(shù)據(jù)。

tabModel->setRelation(2, QSqlRelation("Departments", "departID", "department"));

設(shè)置表格的選擇模型和代理

代碼設(shè)置了表格的選擇模型,并為表格設(shè)置了一個關(guān)系型代理(QSqlRelationalDelegate),以便在表格中顯示關(guān)聯(lián)表的數(shù)據(jù)而不是外鍵的值。

theSelection = new QItemSelectionModel(tabModel);
ui->tableView->setModel(tabModel);
ui->tableView->setSelectionModel(theSelection);
ui->tableView->setItemDelegate(new QSqlRelationalDelegate(ui->tableView));

選擇并顯示數(shù)據(jù)表

最后,通過調(diào)用 select 方法來選擇和顯示數(shù)據(jù)表的內(nèi)容。

tabModel->select();

其實代碼中最重要的部分就是setRelation,我們只要確保數(shù)據(jù)庫文件正確,并且 Student 表和 Departments 表存在,并且在 Student 表中的 “學(xué)院” 列與 Departments 表中的 "departID" 列正確關(guān)聯(lián)即可,其他的就交給組件來處理,如下圖所示;

到此這篇關(guān)于Qt實現(xiàn)SqlRelationalTable關(guān)聯(lián)表組件的文章就介紹到這了,更多相關(guān)Qt SqlRelationalTable關(guān)聯(lián)表內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論