溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

C/C++中的Qt?StandardItemModel數(shù)據(jù)模型怎么使用

發(fā)布時(shí)間:2021-12-06 10:07:30 來源:億速云 閱讀:127 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要講解了“C/C++中的Qt StandardItemModel數(shù)據(jù)模型怎么使用”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“C/C++中的Qt StandardItemModel數(shù)據(jù)模型怎么使用”吧!

QStandardItemModel 是標(biāo)準(zhǔn)的以項(xiàng)數(shù)據(jù)為單位的基于M/V模型的一種標(biāo)準(zhǔn)數(shù)據(jù)管理方式,Model/View 是Qt中的一種數(shù)據(jù)編排結(jié)構(gòu),其中Model代表模型,View代表視圖,視圖是顯示和編輯數(shù)據(jù)的界面組件,而模型則是視圖與原始數(shù)據(jù)之間的接口,通常該類結(jié)構(gòu)都是用在數(shù)據(jù)庫中較多,例如模型結(jié)構(gòu)負(fù)責(zé)讀取或?qū)懭霐?shù)據(jù)庫,視圖結(jié)構(gòu)則負(fù)責(zé)展示數(shù)據(jù),其條理清晰,編寫代碼便于維護(hù)。

QStandardItemModel組件通常會配合TableView組件一起使用,當(dāng)數(shù)據(jù)庫或文本中的記錄發(fā)生變化時(shí)會自動同步到組件中,首先繪制UI界面。

C/C++中的Qt?StandardItemModel數(shù)據(jù)模型怎么使用

其次綁定頂部ToolBar菜單,分別對菜單增加對應(yīng)的功能屬性的描述等。

C/C++中的Qt?StandardItemModel數(shù)據(jù)模型怎么使用

初始化構(gòu)造函數(shù): 當(dāng)程序運(yùn)行時(shí),我們需要對頁面中的控件逐一初始化,并將Table表格與模型通過調(diào)用ui->tableView->setModel(model)進(jìn)行綁定。

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <iostream>
#include <QLabel>
#include <QStandardItem>
#include <QItemSelectionModel>

#include <QFileDialog>
#include <QTextStream>

#include <QList>

// 默認(rèn)構(gòu)造函數(shù)
// https://www.cnblogs.com/lyshark
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // 初始化部分
    model = new QStandardItemModel(3,FixedColumnCount,this);  // 數(shù)據(jù)模型初始化
    selection = new QItemSelectionModel(model);               // Item選擇模型

    // 為TableView設(shè)置數(shù)據(jù)模型
    ui->tableView->setModel(model);               // 設(shè)置數(shù)據(jù)模型
    ui->tableView->setSelectionModel(selection);  // 設(shè)置選擇模型

    // 默認(rèn)禁用所有Action選項(xiàng),只保留打開
    ui->actionSave->setEnabled(false);
    ui->actionView->setEnabled(false);
    ui->actionAppend->setEnabled(false);
    ui->actionDelete->setEnabled(false);
    ui->actionInsert->setEnabled(false);

    // 創(chuàng)建狀態(tài)欄組件,主要來顯示單元格位置
    LabCurFile = new QLabel("當(dāng)前文件:",this);
    LabCurFile->setMinimumWidth(200);

    LabCellPos = new QLabel("當(dāng)前單元格:",this);
    LabCellPos->setMinimumWidth(180);
    LabCellPos->setAlignment(Qt::AlignHCenter);

    LabCellText = new QLabel("單元格內(nèi)容:",this);
    LabCellText->setMinimumWidth(150);

    ui->statusbar->addWidget(LabCurFile);
    ui->statusbar->addWidget(LabCellPos);
    ui->statusbar->addWidget(LabCellText);

    //選擇當(dāng)前單元格變化時(shí)的信號與槽
    connect(selection,SIGNAL(currentChanged(QModelIndex,QModelIndex)),this,SLOT(on_currentChanged(QModelIndex,QModelIndex)));
}

MainWindow::~MainWindow()
{
    delete ui;
}

初始化時(shí)同時(shí)需要綁定一個(gè)on_currentChanged(QModelIndex,QModelIndex)信號,當(dāng)用戶選中指定單元格時(shí)相應(yīng)用戶。

// 選擇單元格變化時(shí)的響應(yīng),通過在構(gòu)造函數(shù)中綁定信號和槽函數(shù)實(shí)現(xiàn)觸發(fā)
// https://www.cnblogs.com/lyshark
void MainWindow::on_currentChanged(const QModelIndex &current, const QModelIndex &previous)
{
   Q_UNUSED(previous);

    if (current.isValid()) //當(dāng)前模型索引有效
    {
        LabCellPos->setText(QString::asprintf("當(dāng)前單元格:%d行,%d列",current.row(),current.column())); //顯示模型索引的行和列號
        QStandardItem   *aItem;
        aItem=model->itemFromIndex(current); //從模型索引獲得Item
        this->LabCellText->setText("單元格內(nèi)容:"+aItem->text()); //顯示item的文字內(nèi)容
    }
}

當(dāng)頁面被初始化時(shí),默認(rèn)界面如下:

C/C++中的Qt?StandardItemModel數(shù)據(jù)模型怎么使用

打開并填充組件: 當(dāng)工具欄中打開文件被點(diǎn)擊后則觸發(fā),打開文件時(shí)通過aFile.open打開,循環(huán)讀入文件,并將文件中的內(nèi)容逐行追加到QStringList fFileContent中,當(dāng)追加完畢后,直接調(diào)用iniModelFromStringList(fFileContent);完成對頁面TableView組件的初始化,并設(shè)置其他控件狀態(tài)為可點(diǎn)擊。

void MainWindow::on_actionOpen_triggered()
{
    QString curPath=QCoreApplication::applicationDirPath(); // 獲取應(yīng)用程序的路徑
    
    // 調(diào)用打開文件對話框打開一個(gè)文件
    // https://www.cnblogs.com/lyshark
    QString aFileName=QFileDialog::getOpenFileName(this,"打開一個(gè)文件",curPath,"數(shù)據(jù)文件(*.txt);;所有文件(*.*)");
    if (aFileName.isEmpty())
    {
        return; // 如果未選擇文件則退出
    }

    QStringList fFileContent;                              // 文件內(nèi)容字符串列表
    QFile aFile(aFileName);                                // 以文件方式讀出
    if (aFile.open(QIODevice::ReadOnly | QIODevice::Text)) // 以只讀文本方式打開文件
    {
        QTextStream aStream(&aFile);       // 用文本流讀取文件
        ui->plainTextEdit->clear();        // 清空列表

        // 循環(huán)讀取只要不為空
        while (!aStream.atEnd())
        {
            QString str=aStream.readLine();          // 讀取文件的一行
            ui->plainTextEdit->appendPlainText(str); // 添加到文本框顯示
            fFileContent.append(str);                // 添加到StringList
        }
        aFile.close();                               // 關(guān)閉文件

        iniModelFromStringList(fFileContent);        // 從StringList的內(nèi)容初始化數(shù)據(jù)模型
    }

    // 打開文件完成后,就可以將Action全部開啟了
    ui->actionSave->setEnabled(true);
    ui->actionView->setEnabled(true);
    ui->actionAppend->setEnabled(true);
    ui->actionDelete->setEnabled(true);
    ui->actionInsert->setEnabled(true);

    // 打開文件成功后,設(shè)置狀態(tài)欄當(dāng)前文件列
    this->LabCurFile->setText("當(dāng)前文件:"+aFileName);//狀態(tài)欄顯示
}

如上iniModelFromStringList(fFileContent);函數(shù)是后期增加的,我們需要自己實(shí)現(xiàn),該函數(shù)的作用是從傳入的StringList中獲取數(shù)據(jù),并將數(shù)據(jù)初始化到TableView模型中,實(shí)現(xiàn)代碼如下。

void MainWindow::iniModelFromStringList(QStringList& aFileContent)
{
    int rowCnt=aFileContent.count();     // 文本行數(shù),第1行是標(biāo)題
    model->setRowCount(rowCnt-1);        // 實(shí)際數(shù)據(jù)行數(shù),要在標(biāo)題上減去1

    // 設(shè)置表頭
    QString header=aFileContent.at(0);         // 第1行是表頭

    // 一個(gè)或多個(gè)空格、TAB等分隔符隔開的字符串、分解為一個(gè)StringList
    // https://www.cnblogs.com/lyshark
    QStringList headerList=header.split(QRegExp("\\s+"),QString::SkipEmptyParts);
    model->setHorizontalHeaderLabels(headerList); // 設(shè)置表頭文字

    // 設(shè)置表格中的數(shù)據(jù)
    int x = 0,y = 0;
    QStandardItem *Item;

    // 有多少列數(shù)據(jù)就循環(huán)多少次
    // https://www.cnblogs.com/lyshark
    for(x=1; x < rowCnt; x++)
    {
        QString LineText = aFileContent.at(x);    // 獲取數(shù)據(jù)區(qū)的一行

        // 一個(gè)或多個(gè)空格、TAB等分隔符隔開的字符串、分解為一個(gè)StringList
        QStringList tmpList=LineText.split(QRegExp("\\s+"),QString::SkipEmptyParts);

        // 循環(huán)列數(shù),也就是循環(huán)FixedColumnCount,其中tmpList中的內(nèi)容也是.
        for(y=0; y < FixedColumnCount-1; y++)
        {
            Item = new QStandardItem(tmpList.at(y)); // 創(chuàng)建item
            model->setItem(x-1,y,Item);              // 為模型的某個(gè)行列位置設(shè)置Item
        }

        // 最后一個(gè)數(shù)據(jù)需要取出來判斷,并單獨(dú)設(shè)置狀態(tài)
        Item=new QStandardItem(headerList.at(y));   // 最后一列是Checkable,需要設(shè)置
        Item->setCheckable(true);                   // 設(shè)置為Checkable

        // 判斷最后一個(gè)數(shù)值是否為0
        if (tmpList.at(y) == "0")
            Item->setCheckState(Qt::Unchecked);   // 根據(jù)數(shù)據(jù)設(shè)置check狀態(tài)
        else
            Item->setCheckState(Qt::Checked);

        model->setItem(x-1,y,Item); //為模型的某個(gè)行列位置設(shè)置Item
    }
}

初始化組件后效果如下:

C/C++中的Qt?StandardItemModel數(shù)據(jù)模型怎么使用

實(shí)現(xiàn)添加一行數(shù)據(jù): 為TableView添加一行數(shù)據(jù),在文件末尾插入。

void MainWindow::on_actionAppend_triggered()
{
    QList<QStandardItem *> ItemList;   // 創(chuàng)建臨時(shí)容器
    QStandardItem *Item;

    // 模擬添加一列的數(shù)據(jù)
    for(int x=0; x<FixedColumnCount-1; x++)
    {
        Item = new QStandardItem("測試(追加行)");    // 循環(huán)創(chuàng)建每一列
        ItemList << Item;                          // 添加到鏈表中
    }

    // 創(chuàng)建最后一個(gè)列元素,由于是選擇框所以需要單獨(dú)創(chuàng)建
    // https://www.cnblogs.com/lyshark
    // 1.獲取到最后一列的表頭下標(biāo),最后下標(biāo)為6
    QString str = model->headerData(model->columnCount()-1,Qt::Horizontal,Qt::DisplayRole).toString();

    Item=new QStandardItem(str); // 創(chuàng)建 "是否合格" 字段
    Item->setCheckable(true);    // 設(shè)置狀態(tài)為真
    ItemList << Item;            // 最后一個(gè)選項(xiàng)追加進(jìn)去

    model->insertRow(model->rowCount(),ItemList);                 // 插入一行,需要每個(gè)Cell的Item
    QModelIndex curIndex=model->index(model->rowCount()-1,0);     // 創(chuàng)建最后一行的ModelIndex

    selection->clearSelection();                                      // 清空當(dāng)前選中項(xiàng)
    selection->setCurrentIndex(curIndex,QItemSelectionModel::Select); // 設(shè)置當(dāng)前選中項(xiàng)為當(dāng)前選擇行
}

插入代碼演示效果:

C/C++中的Qt?StandardItemModel數(shù)據(jù)模型怎么使用

實(shí)現(xiàn)插入一行數(shù)據(jù): 為TableView插入一行數(shù)據(jù)(在文件任意位置插入數(shù)據(jù))

// https://www.cnblogs.com/lyshark
void MainWindow::on_actionInsert_triggered()
{
    QList<QStandardItem*> ItemList;       // QStandardItem的列表類
    QStandardItem *Item;

    // 模擬插入前五列數(shù)據(jù)
    for(int i=0;i<FixedColumnCount-1;i++)
    {
        Item= new QStandardItem("測試(插入行)");  // 新建一個(gè)QStandardItem
        ItemList << Item;                        // 添加到列表類
    }

    QString str;                               // 獲取表頭文字
    str=model->headerData(model->columnCount()-1,Qt::Horizontal,Qt::DisplayRole).toString();
    Item=new QStandardItem(str);      // 創(chuàng)建Item
    Item->setCheckable(true);         // 設(shè)置為可使用CheckBox
    ItemList<<Item;                   // 添加到列表類

    QModelIndex curIndex=selection->currentIndex(); // 獲取當(dāng)前選中項(xiàng)的索引
    model->insertRow(curIndex.row(),ItemList);      // 在當(dāng)前行的前面插入一行
    selection->clearSelection();                                       // 清除當(dāng)前選中項(xiàng)
    selection->setCurrentIndex(curIndex,QItemSelectionModel::Select);  // 設(shè)置當(dāng)前選中項(xiàng)為當(dāng)前選擇行
}

插入代碼演示效果:

C/C++中的Qt?StandardItemModel數(shù)據(jù)模型怎么使用

實(shí)現(xiàn)刪除一行數(shù)據(jù): 刪除數(shù)據(jù)之前需要通過selection->currentIndex()確定當(dāng)前選中行,并通過model->removeRow()移除即可。

// https://www.cnblogs.com/lyshark
void MainWindow::on_actionDelete_triggered()
{
    QModelIndex curIndex = selection->currentIndex();  // 獲取當(dāng)前選擇單元格的模型索引

    // 先判斷是不是最后一行
    if (curIndex.row()==model->rowCount()-1)
    {
        model->removeRow(curIndex.row()); //刪除最后一行
    }
    else
    {
        model->removeRow(curIndex.row());//刪除一行,并重新設(shè)置當(dāng)前選擇行
        selection->setCurrentIndex(curIndex,QItemSelectionModel::Select);
    }
}

刪除代碼效果演示:

C/C++中的Qt?StandardItemModel數(shù)據(jù)模型怎么使用

實(shí)現(xiàn)字體數(shù)據(jù)對齊: 表格中的字體可以實(shí)現(xiàn)多種對其方式,對齊方式分為 居中對齊,左對齊,右對齊 三種。

// 設(shè)置表格居中對齊
void MainWindow::on_pushButton_clicked()
{
    if (!selection->hasSelection())
        return;

    QModelIndexList selectedIndex=selection->selectedIndexes();

    QModelIndex Index;
    QStandardItem *Item;

    for (int i=0; i<selectedIndex.count(); i++)
    {
        Index=selectedIndex.at(i);
        Item=model->itemFromIndex(Index);
        Item->setTextAlignment(Qt::AlignHCenter);
    }
}

// 設(shè)置表格左對齊
// https://www.cnblogs.com/lyshark
void MainWindow::on_pushButton_2_clicked()
{
    if (!selection->hasSelection()) //沒有選擇的項(xiàng)
        return;

//獲取選擇的單元格的模型索引列表,可以是多選
    QModelIndexList selectedIndex=selection->selectedIndexes();

    for (int i=0;i<selectedIndex.count();i++)
    {
        QModelIndex aIndex=selectedIndex.at(i); //獲取其中的一個(gè)模型索引
        QStandardItem* aItem=model->itemFromIndex(aIndex);//獲取一個(gè)單元格的項(xiàng)數(shù)據(jù)對象
        aItem->setTextAlignment(Qt::AlignLeft);//設(shè)置文字對齊方式
    }
}

// 設(shè)置表格右對齊
void MainWindow::on_pushButton_3_clicked()
{
    if (!selection->hasSelection())
        return;

    QModelIndexList selectedIndex=selection->selectedIndexes();

    QModelIndex aIndex;
    QStandardItem *aItem;

    for (int i=0;i<selectedIndex.count();i++)
    {
        aIndex=selectedIndex.at(i);
        aItem=model->itemFromIndex(aIndex);
        aItem->setTextAlignment(Qt::AlignRight);
    }
}

對齊代碼效果演示:

C/C++中的Qt?StandardItemModel數(shù)據(jù)模型怎么使用

實(shí)現(xiàn)字體數(shù)據(jù)加粗: 將選中行的字體進(jìn)行加粗顯示。

// 設(shè)置字體加粗顯示
// https://www.cnblogs.com/lyshark
void MainWindow::on_pushButton_4_clicked()
{
    if (!selection->hasSelection())
        return;

//獲取選擇單元格的模型索引列表
    QModelIndexList selectedIndex=selection->selectedIndexes();

    for (int i=0;i<selectedIndex.count();i++)
    {
        QModelIndex aIndex=selectedIndex.at(i); //獲取一個(gè)模型索引
        QStandardItem* aItem=model->itemFromIndex(aIndex);//獲取項(xiàng)數(shù)據(jù)
        QFont font=aItem->font(); //獲取字體
        font.setBold(true); //設(shè)置字體是否粗體
        aItem->setFont(font); //重新設(shè)置字體
    }

加粗代碼效果演示:

C/C++中的Qt?StandardItemModel數(shù)據(jù)模型怎么使用

實(shí)現(xiàn)保存文件: 當(dāng)保存文件被點(diǎn)擊后觸發(fā),通過便利TableWidget模型組件中的數(shù)據(jù),并將數(shù)據(jù)通過aStream << str << "\n";寫出到記事本中。

// https://www.cnblogs.com/lyshark
// 【保存文件】
void MainWindow::on_actionSave_triggered()
{
    QString curPath=QCoreApplication::applicationDirPath(); // 獲取應(yīng)用程序的路徑

    // 調(diào)用打開文件對話框選擇一個(gè)文件
    QString aFileName=QFileDialog::getSaveFileName(this,tr("選擇一個(gè)文件"),curPath,"數(shù)據(jù)文件(*.txt);;所有文件(*.*)");

    if (aFileName.isEmpty()) // 未選擇文件則直接退出
        return;

    QFile aFile(aFileName);

    // 以讀寫、覆蓋原有內(nèi)容方式打開文件
    if (!(aFile.open(QIODevice::ReadWrite | QIODevice::Text | QIODevice::Truncate)))
        return;

    QTextStream aStream(&amp;aFile);    // 用文本流讀取文件
    QStandardItem *Item;
    QString str;
    int x = 0,y = 0;

    ui-&gt;plainTextEdit-&gt;clear();

// 獲取表頭文字
    for (x=0; x&lt;model-&gt;columnCount(); x++)
    {
        Item=model-&gt;horizontalHeaderItem(x);     // 獲取表頭的項(xiàng)數(shù)據(jù)
        str= str + Item-&gt;text() + "\t\t";        // 以TAB制表符隔開
    }
    aStream &lt;&lt; str &lt;&lt; "\n";                      // 文件里需要加入換行符\n
    ui-&gt;plainTextEdit-&gt;appendPlainText(str);

// 獲取數(shù)據(jù)區(qū)文字
    for ( x=0; x &lt; model-&gt;rowCount(); x++)
    {
        str = "";
        for( y=0; y &lt; model-&gt;columnCount()-1; y++)
        {
            Item=model-&gt;item(x,y);
            str=str + Item-&gt;text() + QString::asprintf("\t\t");
        }

        // 對最后一列需要轉(zhuǎn)換一下,如果判斷為選中則寫1否則寫0
        Item=model-&gt;item(x,y);
        if (Item-&gt;checkState()==Qt::Checked)
            str= str + "1";
        else
            str= str + "0";

         ui-&gt;plainTextEdit-&gt;appendPlainText(str);
         aStream &lt;&lt; str &lt;&lt; "\n";
    }
}

// 【導(dǎo)出Txt文件】:將TableView中的數(shù)據(jù)導(dǎo)出到PlainTextEdit顯示
void MainWindow::on_actionView_triggered()
{
        ui-&gt;plainTextEdit-&gt;clear();
        QStandardItem *Item;
        QString str;

    //獲取表頭文字
        int x=0,y=0;
        for (x=0; x&lt;model-&gt;columnCount(); x++)
        { //
            Item=model-&gt;horizontalHeaderItem(x);
            str= str + Item-&gt;text() + "\t";
        }
        ui-&gt;plainTextEdit-&gt;appendPlainText(str);

    //獲取數(shù)據(jù)區(qū)的每行
        for (x=0; x&lt;model-&gt;rowCount(); x++)
        {
            str="";
            for(y=0; y&lt;model-&gt;columnCount()-1; y++)
            {
                Item=model-&gt;item(x,y);
                str= str + Item-&gt;text() + QString::asprintf("\t");
            }

            Item=model-&gt;item(x,y);
            if (Item-&gt;checkState()==Qt::Checked)
                str= str + "1";
            else
                str= str + "0";

             ui-&gt;plainTextEdit-&gt;appendPlainText(str);
        }
}

文件保存后如下:

C/C++中的Qt?StandardItemModel數(shù)據(jù)模型怎么使用

感謝各位的閱讀,以上就是“C/C++中的Qt StandardItemModel數(shù)據(jù)模型怎么使用”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對C/C++中的Qt StandardItemModel數(shù)據(jù)模型怎么使用這一問題有了更深刻的體會,具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識點(diǎn)的文章,歡迎關(guān)注!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI