C++ Qt開發:StandardItemModel數據模型組件

来源:https://www.cnblogs.com/LyShark/archive/2023/12/22/17920221.html
-Advertisement-
Play Games

Qt 是一個跨平臺C++圖形界面開發庫,利用Qt可以快速開發跨平臺窗體應用程式,在Qt中我們可以通過拖拽的方式將不同組件放到指定的位置,實現圖形化開發極大的方便了開發效率,本章將重點介紹`StandardItemModel`數據模型組件的常用方法及靈活運用。`QStandardItemModel` ... ...


Qt 是一個跨平臺C++圖形界面開發庫,利用Qt可以快速開發跨平臺窗體應用程式,在Qt中我們可以通過拖拽的方式將不同組件放到指定的位置,實現圖形化開發極大的方便了開發效率,本章將重點介紹StandardItemModel數據模型組件的常用方法及靈活運用。

QStandardItemModel 是 Qt 中用於存儲標準項數據的模型類之一,它繼承自 QAbstractItemModel 類。這個模型提供了一種靈活的方式來組織和管理數據,適用於各種視圖類(比如 QTreeViewQListViewQTableView 等)。該組件是標準的以項數據為單位的基於M/V模型的一種標準數據管理方式。

Model/View 是Qt中的一種數據編排結構,其中Model代表模型而View則代表視圖,視圖是顯示和編輯數據的界面組件,而模型則是視圖與原始數據之間的介面,通常該類結構都是用在資料庫中較多,例如模型結構負責讀取或寫入資料庫,視圖結構則負責展示數據,其條理清晰,編寫代碼便於維護。Model/View架構是Qt中數據與界面分離的核心設計模式,為開發者提供了一種清晰而靈活的方式來管理和展示數據。

數據模型組件通常會配合TableView等相關組件一起使用,首先繪製UI界面,界面中包含頂部ToolBar組件,底部是一個TableView視圖表格,最下方是一個PlainTextEdit文本框,如下圖所示;

如上圖所示ToolBar組件中我們綁定了一些快捷鍵及ICO圖標,這些信息通過圖形化的方式進行了關聯;

1.1 初始化表格

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

方法 描述
QStandardItemModel(int rows, int columns, QObject *parent = nullptr) 構造函數,創建一個具有指定行數和列數的 QStandardItemModel 對象。
virtual ~QStandardItemModel() 虛析構函數,釋放 QStandardItemModel 對象及其所有子項。
int rowCount(const QModelIndex &parent = QModelIndex()) const 返回指定父項的行數。如果 parent 為無效索引,則返回根項的行數。
int columnCount(const QModelIndex &parent = QModelIndex()) const 返回指定父項的列數。如果 parent 為無效索引,則返回根項的列數。
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const 返回指定行、列和父項的索引。
QModelIndex parent(const QModelIndex &child) const 返回指定子項的父項的索引。如果子項沒有父項,則返回無效索引。
Qt::ItemFlags flags(const QModelIndex &index) const 返回指定索引處項的標誌,用於指示該項的狀態和行為。
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const 返回指定索引處項的數據。role 參數指定要獲取的數據的角色,如 Qt::DisplayRole 表示顯示文本。
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) 設置指定索引處項的數據。如果設置成功,則返回 true,否則返回 false
bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) 在指定父項下插入行。返回 true 表示成功。
bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) 從指定父項中移除行。返回 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()) 在指定父項下插入列。返回 true 表示成功。
bool removeColumns(int column, int count, const QModelIndex &parent = QModelIndex()) 從指定父項中移除列。返回 true 表示成功。
Qt::DropActions supportedDropActions() const 返回模型支持的拖放操作。
Qt::DropActions supportedDragActions() const 返回模型支持的拖動操作。
QStringList mimeTypes() const 返回模型支持的 MIME 類型列表。
QMimeData *mimeData(const QModelIndexList &indexes) const 返回包含指定索引項數據的 MIME 數據對象。
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) 處理拖放操作中的 MIME 數據。返回 true 表示成功。

以上是 QStandardItemModel 類的一些常用方法,通過這些方法,可以對模型進行增刪改查等操作,並與視圖進行交互。

首先筆者先來演示一下如何將tableView組件與QStandardItemModel組件進行綁定操作,其實綁定很簡單隻需要調用ui->tableView->setModel即可將tableView組件與model數據集進行綁定,當綁定後,模型中的數據發生變化則會自動刷新到View組件中,我們就無需關心界面中的組件如何顯示了,這個現實過程交給Model映射吧。

如下所示的代碼片段是一個使用 QStandardItemModel 的例子,演示瞭如何創建一個帶有表頭和初始數據的 QTableView

以下是代碼片段的一些說明:

  1. 創建 QStandardItemModel 對象,並設置列數為 3。
  2. 為表頭設置標簽,分別是 "賬號"、"用戶"、"年齡"。
  3. 將模型設置為 QTableView
  4. 設置表頭預設對齊方式為左對齊。
  5. 設置列寬,第一列寬度為 101,第二列寬度為 102。
  6. 迴圈添加數據到模型中,包括 "20210506"、"lyshark" 和 "24"。

這樣,就創建了一個包含表頭和數據的 QTableView,並將其顯示在 MainWindow 中。

// 預設構造函數
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("賬號"));
    model->setHeaderData(1,Qt::Horizontal,QString("用戶"));
    model->setHeaderData(2,Qt::Horizontal,QString("年齡"));

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

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

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

運行後讀者可觀察TableView表格中的變化情況,如下圖所示;

接著,我們來看下如何對本項目中UI表格進行初始化,在MainWindow構造函數中,我們首先創建一個QStandardItemModel用於存儲表格數據,以及一個QItemSelectionModel用於處理表格中的選擇操作,並將它們關聯到TableView組件上。在視窗初始化時,除了打開文件的操作外,禁用了其他所有Action選項。創建狀態欄組件,包括顯示當前文件、當前單元格位置和單元格內容的QLabel組件。

// 預設構造函數
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{
    ui->setupUi(this);

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

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

    // 預設禁用所有Action選項,只保留打開
    ui->actionSave->setEnabled(false);
    ui->actionView->setEnabled(false);
    ui->actionAppend->setEnabled(false);
    ui->actionDelete->setEnabled(false);
    ui->actionInsert->setEnabled(false);

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

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

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

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

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

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

如上代碼中,我們還將選擇模型的currentChanged信號連接到了槽函數on_currentChanged上面,這個槽函數主要用於實現,當選擇單元格變化時則響應,並將當前單元格變化刷新到底部的StatusBar組件上,代碼如下所示;

// 【選中單元格時響應】:選擇單元格變化時的響應,通過在構造函數中綁定信號和槽函數實現觸發
void MainWindow::on_currentChanged(const QModelIndex &current, const QModelIndex &previous)
{
   Q_UNUSED(previous);

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

讀者可自行運行這段程式,當運行後首先會初始化表格的長度及寬度,且頁面中禁用了其他按鈕,只能選擇打開文件選項,如下圖所示;

1.2 打開文件

當讀者點擊打開文件時,首先會觸發on_actionOpen_triggered槽函數,在該函數內,通過QCoreApplication::applicationDirPath()獲取應用程式的路徑,並通過QFileDialog::getOpenFileName()文件對話框讓用戶選擇一個數據文件(*.txt)。如果用戶選擇了文件,就以只讀文本方式打開該文件,讀取文件內容到一個字元串列表 fFileContent 中,並顯示到 plainTextEdit 文本框中。

當讀取結束後,直接關閉文件,並調用 iniModelFromStringList 函數,該函數根據字元串列表的內容初始化數據模型。隨即啟用工具欄中的其他Action選項,包括保存、查看、追加、刪除和插入。併在狀態欄顯示當前打開的文件路徑。

該函數實現了打開文件後的一系列操作,包括讀取文件內容、更新UI顯示和初始化數據模型。

// 【打開文件】:當工具欄中打開文件被點擊後則觸發
void MainWindow::on_actionOpen_triggered()
{
    QString curPath=QCoreApplication::applicationDirPath(); // 獲取應用程式的路徑
    // 調用打開文件對話框打開一個文件
    QString aFileName=QFileDialog::getOpenFileName(this,"打開一個文件",curPath,"數據文件(*.txt);;所有文件(*.*)");
    if (aFileName.isEmpty())
    {
        return; // 如果未選擇文件則退出
    }

    QStringList fFileContent;                              // 文件內容字元串列表
    QFile aFile(aFileName);                                // 以文件方式讀出
    if (aFile.open(QIODevice::ReadOnly | QIODevice::Text)) // 以只讀文本方式打開文件
    {
        QTextStream aStream(&aFile);       // 用文本流讀取文件
        ui->plainTextEdit->clear();        // 清空列表
        // 迴圈讀取只要不為空
        while (!aStream.atEnd())
        {
            QString str=aStream.readLine();          // 讀取文件的一行
            ui->plainTextEdit->appendPlainText(str); // 添加到文本框顯示
            fFileContent.append(str);                // 添加到StringList
        }
        aFile.close();                               // 關閉文件

        iniModelFromStringList(fFileContent);        // 從StringList的內容初始化數據模型
    }

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

    // 打開文件成功後,設置狀態欄當前文件列
    this->LabCurFile->setText("當前文件:"+aFileName);//狀態欄顯示
}

在上述槽函數中並沒有分析iniModelFromStringList(fFileContent)函數的具體實現細節,該函數用於從傳入的字元串列表 aFileContent 中獲取數據,並將數據初始化到 TableView 模型中。

具體步驟如下:

  • 獲取文本行數 rowCnt,第一行是標題。
  • 設置模型的行數為實際數據行數 rowCnt-1,因為第一行是標題。
  • 獲取表頭 header,並將其分割成一個字元串列表 headerList,作為模型的水平表頭標簽。
  • 迴圈處理每一行數據,分割每行的文本為一個字元串列表 tmpList
  • 對於每一行,迴圈處理每一列(不包括最後一列),為模型的某個行列位置設置 QStandardItem
  • 對於每行的最後一列,該列是可檢查的,需要創建 QStandardItem,並設置為可檢查狀態。根據數據判斷是否選中,並設置相應的檢查狀態。
  • QStandardItem 設置到模型的相應行列位置。

這個函數主要完成了從字元串列表中獲取數據並初始化到 TableView 模型的過程,包括表頭的設置、數據的提取和狀態的處理。

// 【初始化填充TableView】:從傳入的StringList中獲取數據,並將數據初始化到TableView模型中
void MainWindow::iniModelFromStringList(QStringList& aFileContent)
{
    int rowCnt=aFileContent.count();     // 文本行數,第1行是標題
    model->setRowCount(rowCnt-1);        // 實際數據行數,要在標題上減去1

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

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

    // 設置表格中的數據
    int x = 0,y = 0;
    QStandardItem *Item;

    // 有多少列數據就迴圈多少次
    for(x=1; x < rowCnt; x++)
    {
        QString LineText = aFileContent.at(x);    // 獲取數據區的一行
        // 一個或多個空格、TAB等分隔符隔開的字元串、分解為一個StringList
        QStringList tmpList=LineText.split(QRegExp("\\s+"),QString::SkipEmptyParts);

        // 迴圈列數,也就是迴圈FixedColumnCount,其中tmpList中的內容也是.
        for(y=0; y < FixedColumnCount-1; y++)
        {
            Item = new QStandardItem(tmpList.at(y)); // 創建item
            model->setItem(x-1,y,Item);              // 為模型的某個行列位置設置Item
        }

        // 最後一個數據需要取出來判斷,並單獨設置狀態
        Item=new QStandardItem(headerList.at(y));   // 最後一列是Checkable,需要設置
        Item->setCheckable(true);                   // 設置為Checkable

        // 判斷最後一個數值是否為0
        if (tmpList.at(y) == "0")
            Item->setCheckState(Qt::Unchecked);     // 根據數據設置check狀態
        else
            Item->setCheckState(Qt::Checked);

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

讀者可自行運行程式,當程式運行後預設只能點擊打開按鈕,點擊打開按鈕後可以選擇項目中的data.txt文本文件,此時就可以將文本中的內容映射到組件中,其輸出效果如下圖所示;

1.3 保存文件

接著我們來看下保存文件與預覽TableView視圖的實現方法,其實保存文件與預覽是一個功能,唯一的區別是保存文件刷新到文件中,而預覽則是刷新到了PlainTextEdit文本框內,但其兩個本質上是一個功能,此處筆者就以保存文件為例來說明如何實現的。

首先,在代碼中同樣是獲取應用程式路徑,同樣是打開文件唯一不同的是這裡使用了getSaveFileName也標志著是打開一個保存對話框,這裡還使用了QFile::Open函數,並設置了QIODevice::ReadWrite寫入模式,接著定義了QTextStream文本流,第一次迴圈將表頭先追加到流中,最後model->rowCount()迴圈表格元素次數,並依次追加文本流到文件。

步驟總結起來如下:

  • 獲取當前應用程式的路徑。
  • 彈出保存文件對話框,讓用戶選擇保存文件的路徑和文件名。
  • 如果用戶未選擇文件,則直接退出。
  • 使用 QFile 打開文件,以讀寫、覆蓋原有內容的方式打開文件。
  • 使用 QTextStream 以文本流的方式讀取文件。
  • 獲取表頭文字,以製表符 \t\t 分隔,寫入文件。
  • 獲取數據區文字,對於每一行的每一列,以製表符 \t\t 分隔,寫入文件。最後一列根據選中狀態寫入 10
  • 將表頭文字和數據區文字分別追加到 plainTextEdit 文本框中。

這個函數主要完成了將 TableView 模型中的數據保存到文件的過程,包括文件的選擇、打開和寫入。

// 【保存文件】:當保存文件被點擊後觸發
void MainWindow::on_actionSave_triggered()
{
    QString curPath=QCoreApplication::applicationDirPath(); // 獲取應用程式的路徑

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

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

    QFile aFile(aFileName);

    // 以讀寫、覆蓋原有內容方式打開文件
    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);     // 獲取表頭的項數據
        str= str + Item->text() + "\t\t";        // 以TAB製表符隔開
    }
    aStream << str << "\n";                      // 文件里需要加入換行符\n
    ui->plainTextEdit->appendPlainText(str);

    // 獲取數據區文字
    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");
        }

        // 對最後一列需要轉換一下,如果判斷為選中則寫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";
    }
}

運行程式後,讀者可以點擊保存文件按鈕,並將其保存到任意位置,此時打開文件,可看到如下圖所示的效果;

1.3 插入與刪除

首先來解釋一下如何添加一行新的行,其實添加與插入原理一致,唯一的區別在於,添加一行新的數據是在行尾加入,這個可以使用model->columnCount()來得到行尾,而插入則是在選中當前selection->currentIndex()行的下方加入行,其他的方式是完全一致的。

如下所示的函數用於在 TableView 中追加一行數據,具體步驟如下:

  1. 創建一個 QList 容器 ItemList 用於存儲一行數據的 QStandardItem
  2. 迴圈創建 FixedColumnCount-1 列的數據,每列的數據都是 "測試(追加行)"。
  3. 創建最後一列的數據,這一列是一個可選框(Check Box),其表頭通過 model->headerData 獲取。將該項設置為可選,並添加到 ItemList 中。
  4. 使用 model->insertRow 插入一行,該行的數據由 ItemList 決定。
  5. 獲取最後一行的 ModelIndex
  6. 清空當前選中項,然後設置當前選中項為最後一行。

這個函數主要用於模擬在 TableView 中追加一行數據,其中包括普通文本和可選框數據。

// 【添加一行】:為TableView添加一行數據(在文件末尾插入)
void MainWindow::on_actionAppend_triggered()
{
    QList<QStandardItem *> ItemList;   // 創建臨時容器
    QStandardItem *Item;

    // 模擬添加一列的數據
    for(int x=0; x<FixedColumnCount-1; x++)
    {
        Item = new QStandardItem("測試(追加行)");    // 迴圈創建每一列
        ItemList << Item;                          // 添加到鏈表中
    }

    // 創建最後一個列元素,由於是選擇框所以需要單獨創建
    // 1.獲取到最後一列的表頭下標,最後下標為6
    QString str = model->headerData(model->columnCount()-1,Qt::Horizontal,Qt::DisplayRole).toString();

    Item=new QStandardItem(str); // 創建 "是否合格" 欄位
    Item->setCheckable(true);    // 設置狀態為真
    ItemList << Item;            // 最後一個選項追加進去

    model->insertRow(model->rowCount(),ItemList);                 // 插入一行,需要每個Cell的Item
    QModelIndex curIndex=model->index(model->rowCount()-1,0);     // 創建最後一行的ModelIndex
    selection->clearSelection();                                      // 清空當前選中項
    selection->setCurrentIndex(curIndex,QItemSelectionModel::Select); // 設置當前選中項為當前選擇行
}

對於刪除來說則更容易實現,只需要通過調用selection->currentIndex()獲取噹噹前單元格模型索引,並通過調用model->removeRow來實現一處即可,此處需要區別一下是不是最後一行,如果是最後一行則直接刪除即可,如果不是則需要在刪除數據後通過setCurrentIndex將索引設置到前一個或第一個元素上,且核心代碼如下所示;

// 【刪除一行】:刪除選中行
void MainWindow::on_actionDelete_triggered()
{
    QModelIndex curIndex = selection->currentIndex();  // 獲取當前選擇單元格的模型索引

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

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

1.4 格式設置

格式設置也是非常常用的功能,例如在Office中就有表格元素居中、表格左對齊、表格右對齊、字體加粗顯示等,在Qt中Table表格就預設自帶了這些功能的支持,通過直接調用setTextAlignment並傳入Qt::AlignHCenter居中、Qt::AlignLeft用於左對齊、Qt::AlignRight用於右對齊、而對於加粗顯示只需要通過調用setFont將加粗厚的文本刷新到表格中即可,這些功能具備相似性,如下是完整的代碼實現;

// 設置表格居中對齊
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);
    }
}

// 設置表格左對齊
void MainWindow::on_pushButton_2_clicked()
{
    // 沒有選擇的項
    if (!selection->hasSelection())
    {
        return;
    }

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

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

// 設置表格右對齊
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);
    }
}

// 設置字體加粗顯示
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);            // 獲取一個模型索引
        QStandardItem* aItem=model->itemFromIndex(aIndex); // 獲取項數據
        QFont font=aItem->font();                          // 獲取字體
        font.setBold(true);                                // 設置字體是否粗體
        aItem->setFont(font);                              // 重新設置字體
    }
}

讀者可依此點擊下圖的四個按鈕來實習那對不同表格元素的個性化處理,當然如果需要保存這些狀態,則還需要單獨存儲表格中的狀態值,在運行程式後依次設置即可;

附件下載

StandardItemModel.zip

文章出處:https://www.cnblogs.com/LyShark/p/17920221.html
本博客所有文章除特別聲明外,均採用 BY-NC-SA 許可協議。轉載請註明出處!
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Detours 代碼倉庫: https://github.com/microsoft/Detours x64寫一個任意地址hook要比x86麻煩的多,所以這裡直接封裝框架來用於x64的hook。 Detours是微軟發佈的一個API hook框架,同時支持x86和x64,看文檔說也支持ARM和ARM ...
  • 一款好用又強大的開源社區,採用主流的互聯網技術架構、全新的UI設計、支持一鍵源碼部署,擁有完整的文章&教程發佈/搜索/評論/統計流程等,代碼完全開源,沒有任何二次封裝,是一個非常適合二次開發/實戰的現代化社區項目。 ...
  • Python 介紹 Python 是一種 高級 的、解釋型 的、通用 的編程語言。其設計哲學強調代碼的可讀性,使用顯著的縮進。Python 是 動態類型 和 垃圾收集 的。 基本語法 設置 Python 環境並開始基礎知識。 文章鏈接:Python 安裝與快速入門 變數 變數用於存儲在電腦程式中引 ...
  • 平時習慣了./和../作為訪問目錄的路徑,但今天使用golang中fs.ReadDir這個函數的時候發現這個習慣是不正確的。 但是常用的命令並沒有分很清楚.和./ 在這幾個命令中使用.或./都可以到達目錄下 ls cd 錯誤示範 package main import ( "fmt" "io/fs" ...
  • 數據的預處理是數據分析,或者機器學習訓練前的重要步驟。通過數據預處理,可以 提高數據質量,處理數據的缺失值、異常值和重覆值等問題,增加數據的準確性和可靠性 整合不同數據,數據的來源和結構可能多種多樣,分析和訓練前要整合成一個數據集 提高數據性能,對數據的值進行變換,規約等(比如無量綱化),讓演算法更加 ...
  • 在實際的業務開發中,我們經常會碰到VO、BO、PO、DTO等對象屬性之間的賦值,當屬性較多的時候我們使用get,set的方式進行賦值的工作量相對較大,因此很多人會選擇使用spring提供的拷貝工具BeanUtils的copyProperties方法完成對象之間屬性的拷貝。通過這種方式可以很大程度上降... ...
  • 馬哥原創:小紅書詳情採集軟體,自動爬取xhs筆記的詳情數據,欄位含:筆記id,筆記鏈接,筆記標題,筆記內容,筆記類型,發佈時間,修改時間,IP屬地,點贊數,收藏數,評論數,轉發數,用戶昵稱,用戶id,用戶主頁鏈接。 ...
  • 內網代理可以實現不想暴露太多信息給外部,但是又能提供內部的完整信息支持,相當於建立了一條可用的HTTP通道。可以在有這方面需求的人優化網路結構。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...