国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

C++ Qt開(kāi)發(fā):StandardItemModel數(shù)據(jù)模型組件

這篇具有很好參考價(jià)值的文章主要介紹了C++ Qt開(kāi)發(fā):StandardItemModel數(shù)據(jù)模型組件。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

Qt 是一個(gè)跨平臺(tái)C++圖形界面開(kāi)發(fā)庫(kù),利用Qt可以快速開(kāi)發(fā)跨平臺(tái)窗體應(yīng)用程序,在Qt中我們可以通過(guò)拖拽的方式將不同組件放到指定的位置,實(shí)現(xiàn)圖形化開(kāi)發(fā)極大的方便了開(kāi)發(fā)效率,本章將重點(diǎn)介紹StandardItemModel數(shù)據(jù)模型組件的常用方法及靈活運(yùn)用。

QStandardItemModel 是 Qt 中用于存儲(chǔ)標(biāo)準(zhǔn)項(xiàng)數(shù)據(jù)的模型類之一,它繼承自 QAbstractItemModel 類。這個(gè)模型提供了一種靈活的方式來(lái)組織和管理數(shù)據(jù),適用于各種視圖類(比如 QTreeView、QListView、QTableView 等)。該組件是標(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ù)庫(kù)中較多,例如模型結(jié)構(gòu)負(fù)責(zé)讀取或?qū)懭霐?shù)據(jù)庫(kù),視圖結(jié)構(gòu)則負(fù)責(zé)展示數(shù)據(jù),其條理清晰,編寫代碼便于維護(hù)。Model/View架構(gòu)是Qt中數(shù)據(jù)與界面分離的核心設(shè)計(jì)模式,為開(kāi)發(fā)者提供了一種清晰而靈活的方式來(lái)管理和展示數(shù)據(jù)。

數(shù)據(jù)模型組件通常會(huì)配合TableView等相關(guān)組件一起使用,首先繪制UI界面,界面中包含頂部ToolBar組件,底部是一個(gè)TableView視圖表格,最下方是一個(gè)PlainTextEdit文本框,如下圖所示;

C++ Qt開(kāi)發(fā):StandardItemModel數(shù)據(jù)模型組件

如上圖所示ToolBar組件中我們綁定了一些快捷鍵及ICO圖標(biāo),這些信息通過(guò)圖形化的方式進(jìn)行了關(guān)聯(lián);

C++ Qt開(kāi)發(fā):StandardItemModel數(shù)據(jù)模型組件

1.1 初始化表格

為了能充分展示QStandardItemModel模型組件的使用,我們首先簡(jiǎn)單的的介紹一下該組件的常用方法與描述,下面是 QStandardItemModel 類的一些常用方法,說(shuō)明和概述:

方法 描述
QStandardItemModel(int rows, int columns, QObject *parent = nullptr) 構(gòu)造函數(shù),創(chuàng)建一個(gè)具有指定行數(shù)和列數(shù)的 QStandardItemModel 對(duì)象。
virtual ~QStandardItemModel() 虛析構(gòu)函數(shù),釋放 QStandardItemModel 對(duì)象及其所有子項(xiàng)。
int rowCount(const QModelIndex &parent = QModelIndex()) const 返回指定父項(xiàng)的行數(shù)。如果 parent 為無(wú)效索引,則返回根項(xiàng)的行數(shù)。
int columnCount(const QModelIndex &parent = QModelIndex()) const 返回指定父項(xiàng)的列數(shù)。如果 parent 為無(wú)效索引,則返回根項(xiàng)的列數(shù)。
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const 返回指定行、列和父項(xiàng)的索引。
QModelIndex parent(const QModelIndex &child) const 返回指定子項(xiàng)的父項(xiàng)的索引。如果子項(xiàng)沒(méi)有父項(xiàng),則返回?zé)o效索引。
Qt::ItemFlags flags(const QModelIndex &index) const 返回指定索引處項(xiàng)的標(biāo)志,用于指示該項(xiàng)的狀態(tài)和行為。
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const 返回指定索引處項(xiàng)的數(shù)據(jù)。role 參數(shù)指定要獲取的數(shù)據(jù)的角色,如 Qt::DisplayRole 表示顯示文本。
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) 設(shè)置指定索引處項(xiàng)的數(shù)據(jù)。如果設(shè)置成功,則返回 true,否則返回 false
bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) 在指定父項(xiàng)下插入行。返回 true 表示成功。
bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) 從指定父項(xiàng)中移除行。返回 true 表示成功。
QModelIndexList match(const QModelIndex &start, int role, const QVariant &value, int hits = 1, Qt::MatchFlags flags = Qt::MatchFlags(Qt::MatchStartsWithQt::MatchWrap)) const 從模型中匹配指定的字符串等變量。
bool insertColumns(int column, int count, const QModelIndex &parent = QModelIndex()) 在指定父項(xiàng)下插入列。返回 true 表示成功。
bool removeColumns(int column, int count, const QModelIndex &parent = QModelIndex()) 從指定父項(xiàng)中移除列。返回 true 表示成功。
Qt::DropActions supportedDropActions() const 返回模型支持的拖放操作。
Qt::DropActions supportedDragActions() const 返回模型支持的拖動(dòng)操作。
QStringList mimeTypes() const 返回模型支持的 MIME 類型列表。
QMimeData *mimeData(const QModelIndexList &indexes) const 返回包含指定索引項(xiàng)數(shù)據(jù)的 MIME 數(shù)據(jù)對(duì)象。
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) 處理拖放操作中的 MIME 數(shù)據(jù)。返回 true 表示成功。

以上是 QStandardItemModel 類的一些常用方法,通過(guò)這些方法,可以對(duì)模型進(jìn)行增刪改查等操作,并與視圖進(jìn)行交互。

首先筆者先來(lái)演示一下如何將tableView組件與QStandardItemModel組件進(jìn)行綁定操作,其實(shí)綁定很簡(jiǎn)單只需要調(diào)用ui->tableView->setModel即可將tableView組件與model數(shù)據(jù)集進(jìn)行綁定,當(dāng)綁定后,模型中的數(shù)據(jù)發(fā)生變化則會(huì)自動(dòng)刷新到View組件中,我們就無(wú)需關(guān)心界面中的組件如何顯示了,這個(gè)現(xiàn)實(shí)過(guò)程交給Model映射吧。

如下所示的代碼片段是一個(gè)使用 QStandardItemModel 的例子,演示了如何創(chuàng)建一個(gè)帶有表頭和初始數(shù)據(jù)的 QTableView

以下是代碼片段的一些說(shuō)明:

  1. 創(chuàng)建 QStandardItemModel 對(duì)象,并設(shè)置列數(shù)為 3。
  2. 為表頭設(shè)置標(biāo)簽,分別是 "賬號(hào)"、"用戶"、"年齡"。
  3. 將模型設(shè)置為 QTableView。
  4. 設(shè)置表頭默認(rèn)對(duì)齊方式為左對(duì)齊。
  5. 設(shè)置列寬,第一列寬度為 101,第二列寬度為 102。
  6. 循環(huán)添加數(shù)據(jù)到模型中,包括 "20210506"、"lyshark" 和 "24"。

這樣,就創(chuàng)建了一個(gè)包含表頭和數(shù)據(jù)的 QTableView,并將其顯示在 MainWindow 中。

// 默認(rèn)構(gòu)造函數(shù)
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    QStandardItemModel *model = new QStandardItemModel();

    // 初始化tableView表頭
    model->setColumnCount(3);
    model->setHeaderData(0,Qt::Horizontal,QString("賬號(hào)"));
    model->setHeaderData(1,Qt::Horizontal,QString("用戶"));
    model->setHeaderData(2,Qt::Horizontal,QString("年齡"));

    ui->tableView->setModel(model);
    ui->tableView->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);  // 表頭居左顯示

    // 設(shè)置列寬
    ui->tableView->setColumnWidth(0,101);
    ui->tableView->setColumnWidth(1,102);
    
    // 循環(huán)初始化設(shè)置模型
    for(int i = 0; i < 5; i++)
    {
        model->setItem(i,0,new QStandardItem("20210506"));

        // 設(shè)置字符顏色
        model->item(i,0)->setForeground(QBrush(QColor(255, 0, 0)));
        // 設(shè)置字符位置
        model->item(i,0)->setTextAlignment(Qt::AlignCenter);
        model->setItem(i,1,new QStandardItem(QString("lyshark")));
        model->setItem(i,2,new QStandardItem(QString("24")));
    }
}

運(yùn)行后讀者可觀察TableView表格中的變化情況,如下圖所示;

C++ Qt開(kāi)發(fā):StandardItemModel數(shù)據(jù)模型組件

接著,我們來(lái)看下如何對(duì)本項(xiàng)目中UI表格進(jìn)行初始化,在MainWindow構(gòu)造函數(shù)中,我們首先創(chuàng)建一個(gè)QStandardItemModel用于存儲(chǔ)表格數(shù)據(jù),以及一個(gè)QItemSelectionModel用于處理表格中的選擇操作,并將它們關(guān)聯(lián)到TableView組件上。在窗口初始化時(shí),除了打開(kāi)文件的操作外,禁用了其他所有Action選項(xiàng)。創(chuàng)建狀態(tài)欄組件,包括顯示當(dāng)前文件、當(dāng)前單元格位置和單元格內(nèi)容的QLabel組件。

// 默認(rèn)構(gòu)造函數(shù)
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),只保留打開(kāi)
    ui->actionSave->setEnabled(false);
    ui->actionView->setEnabled(false);
    ui->actionAppend->setEnabled(false);
    ui->actionDelete->setEnabled(false);
    ui->actionInsert->setEnabled(false);

    // 創(chuàng)建狀態(tài)欄組件,主要來(lá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í)的信號(hào)與槽
    connect(selection,SIGNAL(currentChanged(QModelIndex,QModelIndex)),this,SLOT(on_currentChanged(QModelIndex,QModelIndex)));
}

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

如上代碼中,我們還將選擇模型的currentChanged信號(hào)連接到了槽函數(shù)on_currentChanged上面,這個(gè)槽函數(shù)主要用于實(shí)現(xiàn),當(dāng)選擇單元格變化時(shí)則響應(yīng),并將當(dāng)前單元格變化刷新到底部的StatusBar組件上,代碼如下所示;

// 【選中單元格時(shí)響應(yīng)】:選擇單元格變化時(shí)的響應(yīng),通過(guò)在構(gòu)造函數(shù)中綁定信號(hào)和槽函數(shù)實(shí)現(xiàn)觸發(fā)
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())); // 顯示模型索引的行和列號(hào)
        QStandardItem   *aItem;
        aItem=model->itemFromIndex(current);                      // 從模型索引獲得Item
        this->LabCellText->setText("單元格內(nèi)容:"+aItem->text());   // 顯示item的文字內(nèi)容
    }
}

讀者可自行運(yùn)行這段程序,當(dāng)運(yùn)行后首先會(huì)初始化表格的長(zhǎng)度及寬度,且頁(yè)面中禁用了其他按鈕,只能選擇打開(kāi)文件選項(xiàng),如下圖所示;

C++ Qt開(kāi)發(fā):StandardItemModel數(shù)據(jù)模型組件

1.2 打開(kāi)文件

當(dāng)讀者點(diǎn)擊打開(kāi)文件時(shí),首先會(huì)觸發(fā)on_actionOpen_triggered槽函數(shù),在該函數(shù)內(nèi),通過(guò)QCoreApplication::applicationDirPath()獲取應(yīng)用程序的路徑,并通過(guò)QFileDialog::getOpenFileName()文件對(duì)話框讓用戶選擇一個(gè)數(shù)據(jù)文件(*.txt)。如果用戶選擇了文件,就以只讀文本方式打開(kāi)該文件,讀取文件內(nèi)容到一個(gè)字符串列表 fFileContent 中,并顯示到 plainTextEdit 文本框中。

當(dāng)讀取結(jié)束后,直接關(guān)閉文件,并調(diào)用 iniModelFromStringList 函數(shù),該函數(shù)根據(jù)字符串列表的內(nèi)容初始化數(shù)據(jù)模型。隨即啟用工具欄中的其他Action選項(xiàng),包括保存、查看、追加、刪除和插入。并在狀態(tài)欄顯示當(dāng)前打開(kāi)的文件路徑。

該函數(shù)實(shí)現(xiàn)了打開(kāi)文件后的一系列操作,包括讀取文件內(nèi)容、更新UI顯示和初始化數(shù)據(jù)模型。

// 【打開(kāi)文件】:當(dāng)工具欄中打開(kāi)文件被點(diǎn)擊后則觸發(fā)
void MainWindow::on_actionOpen_triggered()
{
    QString curPath=QCoreApplication::applicationDirPath(); // 獲取應(yīng)用程序的路徑
    // 調(diào)用打開(kāi)文件對(duì)話框打開(kāi)一個(gè)文件
    QString aFileName=QFileDialog::getOpenFileName(this,"打開(kāi)一個(gè)文件",curPath,"數(shù)據(jù)文件(*.txt);;所有文件(*.*)");
    if (aFileName.isEmpty())
    {
        return; // 如果未選擇文件則退出
    }

    QStringList fFileContent;                              // 文件內(nèi)容字符串列表
    QFile aFile(aFileName);                                // 以文件方式讀出
    if (aFile.open(QIODevice::ReadOnly | QIODevice::Text)) // 以只讀文本方式打開(kāi)文件
    {
        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ù)模型
    }

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

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

在上述槽函數(shù)中并沒(méi)有分析iniModelFromStringList(fFileContent)函數(shù)的具體實(shí)現(xiàn)細(xì)節(jié),該函數(shù)用于從傳入的字符串列表 aFileContent 中獲取數(shù)據(jù),并將數(shù)據(jù)初始化到 TableView 模型中。

具體步驟如下:

  • 獲取文本行數(shù) rowCnt,第一行是標(biāo)題。
  • 設(shè)置模型的行數(shù)為實(shí)際數(shù)據(jù)行數(shù) rowCnt-1,因?yàn)榈谝恍惺菢?biāo)題。
  • 獲取表頭 header,并將其分割成一個(gè)字符串列表 headerList,作為模型的水平表頭標(biāo)簽。
  • 循環(huán)處理每一行數(shù)據(jù),分割每行的文本為一個(gè)字符串列表 tmpList
  • 對(duì)于每一行,循環(huán)處理每一列(不包括最后一列),為模型的某個(gè)行列位置設(shè)置 QStandardItem。
  • 對(duì)于每行的最后一列,該列是可檢查的,需要?jiǎng)?chuàng)建 QStandardItem,并設(shè)置為可檢查狀態(tài)。根據(jù)數(shù)據(jù)判斷是否選中,并設(shè)置相應(yīng)的檢查狀態(tài)。
  • QStandardItem 設(shè)置到模型的相應(yīng)行列位置。

這個(gè)函數(shù)主要完成了從字符串列表中獲取數(shù)據(jù)并初始化到 TableView 模型的過(guò)程,包括表頭的設(shè)置、數(shù)據(jù)的提取和狀態(tài)的處理。

// 【初始化填充TableView】:從傳入的StringList中獲取數(shù)據(jù),并將數(shù)據(jù)初始化到TableView模型中
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等分隔符隔開(kāi)的字符串、分解為一個(gè)StringList
    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)多少次
    for(x=1; x < rowCnt; x++)
    {
        QString LineText = aFileContent.at(x);    // 獲取數(shù)據(jù)區(qū)的一行
        // 一個(gè)或多個(gè)空格、TAB等分隔符隔開(kāi)的字符串、分解為一個(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ù)需要取出來(lái)判斷,并單獨(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
    }
}

讀者可自行運(yùn)行程序,當(dāng)程序運(yùn)行后默認(rèn)只能點(diǎn)擊打開(kāi)按鈕,點(diǎn)擊打開(kāi)按鈕后可以選擇項(xiàng)目中的data.txt文本文件,此時(shí)就可以將文本中的內(nèi)容映射到組件中,其輸出效果如下圖所示;

C++ Qt開(kāi)發(fā):StandardItemModel數(shù)據(jù)模型組件

1.3 保存文件

接著我們來(lái)看下保存文件與預(yù)覽TableView視圖的實(shí)現(xiàn)方法,其實(shí)保存文件與預(yù)覽是一個(gè)功能,唯一的區(qū)別是保存文件刷新到文件中,而預(yù)覽則是刷新到了PlainTextEdit文本框內(nèi),但其兩個(gè)本質(zhì)上是一個(gè)功能,此處筆者就以保存文件為例來(lái)說(shuō)明如何實(shí)現(xiàn)的。

首先,在代碼中同樣是獲取應(yīng)用程序路徑,同樣是打開(kāi)文件唯一不同的是這里使用了getSaveFileName也標(biāo)志著是打開(kāi)一個(gè)保存對(duì)話框,這里還使用了QFile::Open函數(shù),并設(shè)置了QIODevice::ReadWrite寫入模式,接著定義了QTextStream文本流,第一次循環(huán)將表頭先追加到流中,最后model->rowCount()循環(huán)表格元素次數(shù),并依次追加文本流到文件。

步驟總結(jié)起來(lái)如下:

  • 獲取當(dāng)前應(yīng)用程序的路徑。
  • 彈出保存文件對(duì)話框,讓用戶選擇保存文件的路徑和文件名。
  • 如果用戶未選擇文件,則直接退出。
  • 使用 QFile 打開(kāi)文件,以讀寫、覆蓋原有內(nèi)容的方式打開(kāi)文件。
  • 使用 QTextStream 以文本流的方式讀取文件。
  • 獲取表頭文字,以制表符 \t\t 分隔,寫入文件。
  • 獲取數(shù)據(jù)區(qū)文字,對(duì)于每一行的每一列,以制表符 \t\t 分隔,寫入文件。最后一列根據(jù)選中狀態(tài)寫入 10。
  • 將表頭文字和數(shù)據(jù)區(qū)文字分別追加到 plainTextEdit 文本框中。

這個(gè)函數(shù)主要完成了將 TableView 模型中的數(shù)據(jù)保存到文件的過(guò)程,包括文件的選擇、打開(kāi)和寫入。

// 【保存文件】:當(dāng)保存文件被點(diǎn)擊后觸發(fā)
void MainWindow::on_actionSave_triggered()
{
    QString curPath=QCoreApplication::applicationDirPath(); // 獲取應(yīng)用程序的路徑

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

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

    QFile aFile(aFileName);

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

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

    ui->plainTextEdit->clear();

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

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

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

         ui->plainTextEdit->appendPlainText(str);
         aStream << str << "\n";
    }
}

運(yùn)行程序后,讀者可以點(diǎn)擊保存文件按鈕,并將其保存到任意位置,此時(shí)打開(kāi)文件,可看到如下圖所示的效果;

C++ Qt開(kāi)發(fā):StandardItemModel數(shù)據(jù)模型組件

1.3 插入與刪除

首先來(lái)解釋一下如何添加一行新的行,其實(shí)添加與插入原理一致,唯一的區(qū)別在于,添加一行新的數(shù)據(jù)是在行尾加入,這個(gè)可以使用model->columnCount()來(lái)得到行尾,而插入則是在選中當(dāng)前selection->currentIndex()行的下方加入行,其他的方式是完全一致的。

如下所示的函數(shù)用于在 TableView 中追加一行數(shù)據(jù),具體步驟如下:

  1. 創(chuàng)建一個(gè) QList 容器 ItemList 用于存儲(chǔ)一行數(shù)據(jù)的 QStandardItem。
  2. 循環(huán)創(chuàng)建 FixedColumnCount-1 列的數(shù)據(jù),每列的數(shù)據(jù)都是 "測(cè)試(追加行)"。
  3. 創(chuàng)建最后一列的數(shù)據(jù),這一列是一個(gè)可選框(Check Box),其表頭通過(guò) model->headerData 獲取。將該項(xiàng)設(shè)置為可選,并添加到 ItemList 中。
  4. 使用 model->insertRow 插入一行,該行的數(shù)據(jù)由 ItemList 決定。
  5. 獲取最后一行的 ModelIndex。
  6. 清空當(dāng)前選中項(xiàng),然后設(shè)置當(dāng)前選中項(xiàng)為最后一行。

這個(gè)函數(shù)主要用于模擬在 TableView 中追加一行數(shù)據(jù),其中包括普通文本和可選框數(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("測(cè)試(追加行)");    // 循環(huán)創(chuàng)建每一列
        ItemList << Item;                          // 添加到鏈表中
    }

    // 創(chuàng)建最后一個(gè)列元素,由于是選擇框所以需要單獨(dú)創(chuàng)建
    // 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)前選擇行
}

對(duì)于刪除來(lái)說(shuō)則更容易實(shí)現(xiàn),只需要通過(guò)調(diào)用selection->currentIndex()獲取當(dāng)當(dāng)前單元格模型索引,并通過(guò)調(diào)用model->removeRow來(lái)實(shí)現(xiàn)一處即可,此處需要區(qū)別一下是不是最后一行,如果是最后一行則直接刪除即可,如果不是則需要在刪除數(shù)據(jù)后通過(guò)setCurrentIndex將索引設(shè)置到前一個(gè)或第一個(gè)元素上,且核心代碼如下所示;

// 【刪除一行】:刪除選中行
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);
    }
}

讀者可自行點(diǎn)擊添加一行與插入行,觀察變化則可以理解兩者的區(qū)別,如下圖所示;

C++ Qt開(kāi)發(fā):StandardItemModel數(shù)據(jù)模型組件

1.4 格式設(shè)置

格式設(shè)置也是非常常用的功能,例如在Office中就有表格元素居中、表格左對(duì)齊、表格右對(duì)齊、字體加粗顯示等,在Qt中Table表格就默認(rèn)自帶了這些功能的支持,通過(guò)直接調(diào)用setTextAlignment并傳入Qt::AlignHCenter居中、Qt::AlignLeft用于左對(duì)齊、Qt::AlignRight用于右對(duì)齊、而對(duì)于加粗顯示只需要通過(guò)調(diào)用setFont將加粗厚的文本刷新到表格中即可,這些功能具備相似性,如下是完整的代碼實(shí)現(xiàn);

// 設(shè)置表格居中對(duì)齊
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è)置表格左對(duì)齊
void MainWindow::on_pushButton_2_clicked()
{
    // 沒(méi)有選擇的項(xiàng)
    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);  // 獲取一個(gè)單元格的項(xiàng)數(shù)據(jù)對(duì)象
        aItem->setTextAlignment(Qt::AlignLeft);             // 設(shè)置文字對(duì)齊方式
    }
}

// 設(shè)置表格右對(duì)齊
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);
    }
}

// 設(shè)置字體加粗顯示
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è)置字體
    }
}

讀者可依此點(diǎn)擊下圖的四個(gè)按鈕來(lái)實(shí)習(xí)那對(duì)不同表格元素的個(gè)性化處理,當(dāng)然如果需要保存這些狀態(tài),則還需要單獨(dú)存儲(chǔ)表格中的狀態(tài)值,在運(yùn)行程序后依次設(shè)置即可;

C++ Qt開(kāi)發(fā):StandardItemModel數(shù)據(jù)模型組件

附件下載

StandardItemModel.zip文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-760317.html

到了這里,關(guān)于C++ Qt開(kāi)發(fā):StandardItemModel數(shù)據(jù)模型組件的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • C++ Qt開(kāi)發(fā):TableWidget表格組件

    C++ Qt開(kāi)發(fā):TableWidget表格組件

    Qt 是一個(gè)跨平臺(tái)C++圖形界面開(kāi)發(fā)庫(kù),利用Qt可以快速開(kāi)發(fā)跨平臺(tái)窗體應(yīng)用程序,在Qt中我們可以通過(guò)拖拽的方式將不同組件放到指定的位置,實(shí)現(xiàn)圖形化開(kāi)發(fā)極大的方便了開(kāi)發(fā)效率,本章將重點(diǎn)介紹 TableWidget 表格組件的常用方法及靈活運(yùn)用。 QTableWidget 是 Qt 中用于顯示表格數(shù)

    2024年02月04日
    瀏覽(27)
  • C++ Qt開(kāi)發(fā):PushButton按鈕組件

    C++ Qt開(kāi)發(fā):PushButton按鈕組件

    Qt 是一個(gè)跨平臺(tái)C++圖形界面開(kāi)發(fā)庫(kù),利用Qt可以快速開(kāi)發(fā)跨平臺(tái)窗體應(yīng)用程序,在Qt中我們可以通過(guò)拖拽的方式將不同組件放到指定的位置,實(shí)現(xiàn)圖形化開(kāi)發(fā)極大的方便了開(kāi)發(fā)效率,本章將重點(diǎn)介紹 QPushButton 按鈕組件的常用方法及靈活運(yùn)用。 QPushButton 是 Qt 框架中用于創(chuàng)建按鈕

    2024年02月05日
    瀏覽(23)
  • C++ Qt開(kāi)發(fā):LineEdit單行輸入組件

    C++ Qt開(kāi)發(fā):LineEdit單行輸入組件

    Qt 是一個(gè)跨平臺(tái)C++圖形界面開(kāi)發(fā)庫(kù),利用Qt可以快速開(kāi)發(fā)跨平臺(tái)窗體應(yīng)用程序,在Qt中我們可以通過(guò)拖拽的方式將不同組件放到指定的位置,實(shí)現(xiàn)圖形化開(kāi)發(fā)極大的方便了開(kāi)發(fā)效率,本章將重點(diǎn)介紹 LineEdit 單行輸入框組件的常用方法及靈活運(yùn)用。 在Qt中, QLineEdit 是一個(gè)用于輸

    2024年02月05日
    瀏覽(22)
  • C++ Qt 開(kāi)發(fā):ListWidget列表框組件

    C++ Qt 開(kāi)發(fā):ListWidget列表框組件

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

    2024年02月04日
    瀏覽(23)
  • C++ Qt開(kāi)發(fā):MdiArea多窗體組件

    C++ Qt開(kāi)發(fā):MdiArea多窗體組件

    Qt 是一個(gè)跨平臺(tái)C++圖形界面開(kāi)發(fā)庫(kù),利用Qt可以快速開(kāi)發(fā)跨平臺(tái)窗體應(yīng)用程序,在Qt中我們可以通過(guò)拖拽的方式將不同組件放到指定的位置,實(shí)現(xiàn)圖形化開(kāi)發(fā)極大的方便了開(kāi)發(fā)效率,本章將重點(diǎn)介紹 MdiArea 組件的常用方法及靈活運(yùn)用。 QMdiArea(Multiple Document Interface Area)是Qt中

    2024年02月04日
    瀏覽(18)
  • C++ Qt開(kāi)發(fā):SqlRelationalTable關(guān)聯(lián)表組件

    C++ Qt開(kāi)發(fā):SqlRelationalTable關(guān)聯(lián)表組件

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

    2024年02月04日
    瀏覽(22)
  • C++ Qt開(kāi)發(fā):DateTime日期時(shí)間組件

    C++ Qt開(kāi)發(fā):DateTime日期時(shí)間組件

    Qt 是一個(gè)跨平臺(tái)C++圖形界面開(kāi)發(fā)庫(kù),利用Qt可以快速開(kāi)發(fā)跨平臺(tái)窗體應(yīng)用程序,在Qt中我們可以通過(guò)拖拽的方式將不同組件放到指定的位置,實(shí)現(xiàn)圖形化開(kāi)發(fā)極大的方便了開(kāi)發(fā)效率,本章將重點(diǎn)介紹 QDateTime 日期與時(shí)間組件的常用方法及靈活運(yùn)用。 在Qt中,日期和時(shí)間的處理通

    2024年02月04日
    瀏覽(27)
  • C++ Qt開(kāi)發(fā):Charts繪圖組件概述

    C++ Qt開(kāi)發(fā):Charts繪圖組件概述

    Qt 是一個(gè)跨平臺(tái)C++圖形界面開(kāi)發(fā)庫(kù),利用Qt可以快速開(kāi)發(fā)跨平臺(tái)窗體應(yīng)用程序,在Qt中我們可以通過(guò)拖拽的方式將不同組件放到指定的位置,實(shí)現(xiàn)圖形化開(kāi)發(fā)極大的方便了開(kāi)發(fā)效率,本章將重點(diǎn)介紹 QCharts 二維繪圖組件的常用方法及靈活運(yùn)用。 Qt Charts 提供了一個(gè)強(qiáng)大且易于使

    2024年02月04日
    瀏覽(29)
  • C++ Qt開(kāi)發(fā):SqlTableModel映射組件應(yīng)用

    C++ Qt開(kāi)發(fā):SqlTableModel映射組件應(yīng)用

    Qt 是一個(gè)跨平臺(tái)C++圖形界面開(kāi)發(fā)庫(kù),利用Qt可以快速開(kāi)發(fā)跨平臺(tái)窗體應(yīng)用程序,在Qt中我們可以通過(guò)拖拽的方式將不同組件放到指定的位置,實(shí)現(xiàn)圖形化開(kāi)發(fā)極大的方便了開(kāi)發(fā)效率,本章將重點(diǎn)介紹 SqlTableModule 組件的常用方法及靈活運(yùn)用。 在多數(shù)情況下我們需要使用SQL的方法

    2024年02月04日
    瀏覽(23)
  • C++ Qt開(kāi)發(fā):TreeWidget 樹(shù)形選擇組件

    C++ Qt開(kāi)發(fā):TreeWidget 樹(shù)形選擇組件

    Qt 是一個(gè)跨平臺(tái)C++圖形界面開(kāi)發(fā)庫(kù),利用Qt可以快速開(kāi)發(fā)跨平臺(tái)窗體應(yīng)用程序,在Qt中我們可以通過(guò)拖拽的方式將不同組件放到指定的位置,實(shí)現(xiàn)圖形化開(kāi)發(fā)極大的方便了開(kāi)發(fā)效率,本章將重點(diǎn)介紹 TreeWidget 樹(shù)形選擇組件的常用方法及靈活運(yùn)用。 QTreeWidget 是 Qt 中的樹(shù)形控件組

    2024年02月04日
    瀏覽(22)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包