C++ Qt開發:TableWidget表格組件

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

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


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

QTableWidget 是 Qt 中用於顯示表格數據的部件。它是 QTableView 的子類,提供了一個簡單的介面,適用於一些不需要使用自定義數據模型的簡單表格場景。該組件可以看作是TreeWidget樹形組件的高級版,表格組件相比於樹結構組件靈活性更高,不僅提供了輸出展示二維表格功能,還可以直接對錶格元素直接進行編輯與修改操作,表格結構分為表頭,表中數據兩部分,表格結構可看作一個二維數組,通過數組行列即可鎖定特定元素。

以下是 QTableWidget 類的一些常用方法的簡要說明:

方法 描述
setItem(int row, int column, QTableWidgetItem *item) 設置指定行和列的項
item(int row, int column) const 返回指定行和列的項
setRowCount(int rows) 設置表格的行數
setColumnCount(int columns) 設置表格的列數
rowCount() const 返回表格的行數
columnCount() const 返回表格的列數
setHorizontalHeaderLabels(const QStringList &labels) 設置水平表頭的標簽
setVerticalHeaderLabels(const QStringList &labels) 設置垂直表頭的標簽
setItemPrototype(QTableWidgetItem *item) 設置原型項,用於在新插入的單元格中創建副本
insertRow(int row) 在指定行插入新行
removeRow(int row) 移除指定行
insertColumn(int column) 在指定列插入新列
removeColumn(int column) 移除指定列
clear() 清空表格的所有內容
clearContents() 清空表格的所有單元格的內容,但保留表頭和行列數
itemAt(int x, int y) const 返回給定坐標下的項
setCurrentItem(QTableWidgetItem *item) 設置當前項,用於指定當前被選擇的項
currentItem() const 返回當前被選擇的項
setCurrentCell(int row, int column) 設置當前單元格,用於指定當前被選擇的單元格
currentRow() const 返回當前被選擇的行號
currentColumn() const 返回當前被選擇的列號
setItemDelegate(QAbstractItemDelegate *delegate) 設置項代理,用於自定義單元格的顯示和編輯方式
setSortingEnabled(bool enable) 啟用或禁用排序功能
sortItems(int column, Qt::SortOrder order) 對指定列進行排序
setEditTriggers(EditTriggers triggers) 設置觸發編輯的事件
editItem(QTableWidgetItem *item) 編輯指定項的內容
openPersistentEditor(QTableWidgetItem *item) 打開指定項的持久編輯器
closePersistentEditor(QTableWidgetItem *item) 關閉指定項的持久編輯器
itemChanged(QTableWidgetItem *item) 當項的內容發生變化時發出的信號
cellClicked(int row, int column) 單元格被單擊時發出的信號
cellDoubleClicked(int row, int column) 單元格被雙擊時發出的信號

這些方法提供了對 QTableWidget 的基本操作和配置的途徑。使用這些方法,你可以動態地調整表格的大小、內容,設置表頭,進行排序,處理編輯觸發事件等。

首先我們準備好UI界面部分,該界麵包含的元素較為複雜,如果找不到這些組件可以參考文章底部的完整案例代碼;

1.1 設置初始表格

如下代碼演示瞭如何使用 QTableWidget 設置表頭。

以下是關於該代碼的一些解釋:

  1. setHorizontalHeaderLabels 方法用於設置水平表頭的標簽。在這裡,headerText_Row 是一個包含列標簽的字元串列表,每個字元串對應一個表格列。
  2. 如果需要設置垂直表頭,可以使用 setVerticalHeaderLabels 方法,將一個包含行標簽的字元串列表傳遞給它。
  3. 可以通過迴圈設置表頭的每個單元格的屬性。在這裡,使用了迴圈遍歷列並創建一個 QTableWidgetItem,設置其字體為粗體、字體大小為8,字體顏色為黑色,然後將其設置為相應列的水平表頭項。

這樣,通過設置表頭的不同屬性,可以使表格更具可讀性和美觀性。

// 設置表頭的實現
void MainWindow::on_pushButton_clicked()
{
    QTableWidgetItem *headerItem;
    QStringList headerText_Row,headerText_Col;
    headerText_Row << "姓 名" << "性 別" << "出生日期" << "民 族" << "分數" << "是否黨員";
    //headerText_Col << "第一行" << "第二行";

    // 設置為水平表頭
    ui->tableWidget->setHorizontalHeaderLabels(headerText_Row);

    // 設置垂直表頭
    //ui->tableWidget->setVerticalHeaderLabels(headerText_Col);

    // 另一種方式: 通過迴圈設置
    ui->tableWidget->setColumnCount(headerText_Row.count());       // 列數設置為與headerText_Row的列相等
    for (int i=0;i<ui->tableWidget->columnCount();i++)             // 列編號從0開始
    {
       headerItem=new QTableWidgetItem(headerText_Row.at(i));      // headerText.at(i) 獲取headerText的i行字元串
       QFont font=headerItem->font();                              // 獲取原有字體設置
       font.setBold(true);                                         // 設置為粗體
       font.setPointSize(8);                                       // 設置字體大小
       headerItem->setTextColor(Qt::black);                        // 設置字體顏色
       headerItem->setFont(font);                                  // 設置字體
       ui->tableWidget->setHorizontalHeaderItem(i,headerItem);     // 設置表頭單元格的Item
    }
}

如下代碼演示瞭如何從 QSpinBox 中讀取數量,並將其設置為 QTableWidget 表格的行數。

以下是關於該代碼的一些解釋:

  1. 通過 ui->spinBox->value() 讀取 QSpinBox 中的值,即用戶選擇的數量。
  2. 使用 setRowCount 方法將讀取到的數量設置為表格的行數。
  3. setAlternatingRowColors(true) 用於交替設置行的底色,以提高可讀性。此方法在交替的行之間使用不同的顏色。

通過這樣的操作,可以動態地設置表格的行數,以適應用戶的需求。

// 從spinBox中讀出數量,並設置TableWidget表格的行數
void MainWindow::on_pushButton_2_clicked()
{
    // 讀取出spinBox中的數據,並將其設置到表格中
    ui->tableWidget->setRowCount(ui->spinBox->value());

    // 行的底色交替採用不同顏色
    ui->tableWidget->setAlternatingRowColors(true);
}

運行程式,分別點擊設置表頭與設置行數,此時讀者會看到如下圖所示的輸出效果,Table表格被初始化了。

1.1 初始化表格

如下代碼中的createItemsARow函數,用於為表格的一行創建各個單元格的 QTableWidgetItem

以下是對該代碼的一些解釋:

  1. 姓名(Name):
    • 使用 QTableWidgetItem 創建一個單元格,並將其類型設置為自定義的 MainWindow::ctName
    • 設置文本對齊格式為水平居中和垂直居中。
    • 使用 setData 方法將學號(StudID)設置為單元格的數據。
    • QTableWidgetItem 添加到表格的指定位置。
  2. 性別(Sex):
    • 使用 QTableWidgetItem 創建一個單元格,並將其類型設置為自定義的 MainWindow::ctSex
    • 根據性別設置對應的圖標。
    • 設置文本對齊格式為水平居中和垂直居中。
    • QTableWidgetItem 添加到表格的指定位置。
  3. 出生日期(birth):
    • 使用 QTableWidgetItem 創建一個單元格,並將其類型設置為自定義的 MainWindow::ctBirth
    • 將日期轉換為字元串,並設置為單元格的文本。
    • 設置文本對齊格式為左對齊和垂直居中。
    • QTableWidgetItem 添加到表格的指定位置。
  4. 民族(Nation):
    • 使用 QTableWidgetItem 創建一個單元格,並將其類型設置為自定義的 MainWindow::ctNation
    • 設置文本對齊格式為水平居中和垂直居中。
    • QTableWidgetItem 添加到表格的指定位置。
  5. 是否黨員(isPM):
    • 使用 QTableWidgetItem 創建一個單元格,並將其類型設置為自定義的 MainWindow::ctPartyM
    • 根據是否黨員設置對應的覆選框狀態。
    • 設置文本對齊格式為水平居中和垂直居中。
    • 設置背景顏色為黃色。
    • QTableWidgetItem 添加到表格的指定位置。
  6. 分數(score):
    • 使用 QTableWidgetItem 創建一個單元格,並將其類型設置為自定義的 MainWindow::ctScore
    • 將分數轉換為字元串,並設置為單元格的文本。
    • 設置文本對齊格式為水平居中和垂直居中。
    • QTableWidgetItem 添加到表格的指定位置。

通過這樣的操作,可以在表格中動態地創建一行,並設置每個單元格的內容和樣式。

// 為一行的單元格創建Items行
void MainWindow::createItemsARow(int rowNo,QString Name,QString Sex,QDate birth,QString Nation,bool isPM,int score)
{
    QTableWidgetItem *item;
    QString str;
    uint StudID=1001;

    // -------------------------------------------------------
    // 姓名
    // -------------------------------------------------------
    // 新建一個Item 設置單元格type為自定義的MainWindow::ctName
    item=new QTableWidgetItem(Name,MainWindow::ctName);

    // 文本對齊格式
    item->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);

    // 學號 = 基數+ 行號
    StudID  +=rowNo;

    // 設置studID為data
    item->setData(Qt::UserRole,QVariant(StudID));

    // 為單元格設置Item
    ui->tableWidget->setItem(rowNo,MainWindow::colName,item);

    // -------------------------------------------------------
    // 性別
    // -------------------------------------------------------
    QIcon icon;

    if (Sex=="男")
    {
        icon.addFile(":/image/boy.ico");
    }
    else
    {
        icon.addFile(":/image/girl.ico");
    }

    // 新建一個Item 設置單元格type為自定義的 MainWindow::ctSex
    item=new  QTableWidgetItem(Sex,MainWindow::ctSex);
    item->setIcon(icon);

    // 為單元格設置Item
    item->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);

    // 為單元格設置Item
    ui->tableWidget->setItem(rowNo,MainWindow::colSex,item);

    // -------------------------------------------------------
    // 出生日期
    // -------------------------------------------------------

    // 日期轉換為字元串
    str=birth.toString("yyyy-MM-dd");

    // 新建一個Item 設置單元格type為自定義的 MainWindow::ctBirth
    item=new  QTableWidgetItem(str,MainWindow::ctBirth);

    // 文本對齊格式
    item->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);

    // 為單元格設置Item
    ui->tableWidget->setItem(rowNo,MainWindow::colBirth,item);

    // -------------------------------------------------------
    // 民族
    // -------------------------------------------------------

    // 新建一個Item 設置單元格type為自定義的 MainWindow::ctNation
    item=new  QTableWidgetItem(Nation,MainWindow::ctNation);

    // 文本對齊格式
    item->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);

    // 為單元格設置Item
    ui->tableWidget->setItem(rowNo,MainWindow::colNation,item);

    // -------------------------------------------------------
    // 是否黨員
    // -------------------------------------------------------

    // 新建一個Item 設置單元格type為自定義的 MainWindow::ctPartyM
    item=new  QTableWidgetItem("群眾",MainWindow::ctPartyM);

    // 文本對齊格式
    item->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
    if (isPM)
    {
        item->setCheckState(Qt::Checked);
    }
    else
    {
        item->setCheckState(Qt::Unchecked);
    }

    // 設置為黃色
    item->setBackgroundColor(Qt::yellow);

    // 為單元格設置Item
    ui->tableWidget->setItem(rowNo,MainWindow::colPartyM,item);

    // -------------------------------------------------------
    // 分數
    // -------------------------------------------------------
    str.setNum(score);

    //新建一個Item 設置單元格type為自定義的 MainWindow::ctPartyM
    item=new  QTableWidgetItem(str,MainWindow::ctScore);

    // 文本對齊格式
    item->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);

    // 為單元格設置Item
    ui->tableWidget->setItem(rowNo,MainWindow::colScore,item);
}

接著我們來看一下如何實現初始化一個表格的,首先我們需要設置好需要填充的數據,當有了這些數據以後直接調用createItemsARow函數,並傳入數據,至此就可以實現創建一行,通過迴圈的方式則可以實現多行的創建。

如下代碼用於初始化表格元素,通過迴圈為每一行添加學生數據。

以下是代碼的主要解釋:

  1. 清除內容:
    • 使用 ui->tableWidget->clearContents() 清除工作區中的內容,但不清除表格結構。
  2. 迴圈添加行數據:
    • 獲取表格的總行數,即數據區的行數。
    • 使用迴圈為每一行添加學生數據。
    • 使用 QString::asprintf 格式化字元串設置學生姓名。
    • 根據行號的奇偶性設置性別,同時設置對應的圖標。
    • 調用 createItemsARow 方法為某一行創建各個單元格的 QTableWidgetItem
  3. 日期處理:
    • 初始日期設定為1997年10月7日。
    • 迴圈中,每次添加行後,將日期加20天。
  4. 黨員標誌處理:
    • 使用布爾變數 isParty 表示學生是否為黨員,每次取反。
    • 將黨員標誌設置為對應的覆選框狀態。

通過這樣的初始化,表格會被填充上預設的學生數據,每一行包含姓名、性別、出生日期、民族、是否黨員和分數等信息。

// 初始化表格元素
void MainWindow::on_pushButton_4_clicked()
{
    QString strName,strSex;
    bool isParty=false;

    QDate birth;
    birth.setDate(1997,10,7);                // 初始化一個日期
    ui->tableWidget->clearContents();        // 只清除工作區中的內容,不清除表格

    int Rows=ui->tableWidget->rowCount();    // 數據區行數

    // 迴圈添加行數據
    for (int i=0;i<Rows;i++)
    {
        strName=QString::asprintf("學生%d",i);   // 學生姓名

        if ((i % 2)==0)                         // 分奇數,偶數行設置性別,及其圖標
            strSex="男";
        else
            strSex="女";

        // 為某一行創建items
        createItemsARow(i, strName, strSex, birth,"漢族",isParty,70);

        // 日期加20天
        birth=birth.addDays(20);
        isParty =!isParty;
    }
}

運行後,通過點擊初始化表格則可以實現對Table的初始化,如下圖所示;

這裡我說一下插入行是如何實現的,插入時只需要通過currentRow()獲取當前游標位置,接著直接調用insertRow(CurRow)新建一行空白數據,最後通過createItemsARow()向該行插入數據即可實現,同樣的刪除行時只需要使用removeRow()即可實現。

1.2 讀數據到文本

如下代碼實現了將QTableWidget中的數據讀入文本框的功能。

以下是代碼的主要解釋:

  1. 清空文本框:
    • 使用 ui->textEdit->clear() 清空文本框內容。
  2. 迴圈遍歷表格行:
    • 通過 ui->tableWidget->rowCount() 獲取表格的行數,進行迴圈遍歷。
  3. 逐列處理數據:
    • 使用內部迴圈 for (int j=0; j<ui->tableWidget->columnCount()-1; j++) 處理每一列的數據,最後一列是黨員狀態,需要單獨處理。
    • 獲取每個單元格的 QTableWidgetItem
    • 使用 cellItem->text() 獲取單元格的文本內容。
    • 將每列的文本內容連接為一行字元串。
  4. 黨員狀態處理:
    • 獲取最後一列(黨員狀態列)的 QTableWidgetItem
    • 使用 cellItem->checkState() 判斷覆選框的狀態,根據狀態判斷是否為黨員。
  5. 添加到文本框:
    • 將每一行的字元串添加到文本框中,使用 ui->textEdit->append(str)

通過這樣的處理,文本框中會顯示表格的內容,每一行包含每個單元格的文本內容,最後一列顯示黨員狀態。

// 將表格中的數據讀入文本框: 將QTableWidget的所有行的內容提取字元串
void MainWindow::on_pushButton_8_clicked()
{
    QString str;
    QTableWidgetItem *cellItem;

    // 先清空一下
    ui->textEdit->clear();

    // 迴圈次數為表格行數,逐行處理
    for(int i=0;i< ui->tableWidget->rowCount();i++)
    {
        str = QString::asprintf("第 %d 行: ",i+1);    // 設置表個第0列

        // 逐列處理,但最後一列是check型,需要單獨處理
        for (int j=0;j<ui->tableWidget->columnCount()-1;j++)
        {
            cellItem = ui->tableWidget->item(i,j);     // 獲取到單元格的Item
            str = str + cellItem->text() + " | ";      // 連接字元串
        }

        // 最後一列的黨員狀態,是一個選擇框,要單獨判斷
        cellItem = ui->tableWidget->item(i,colPartyM);

        // 根據選擇框的狀態來單獨判斷
        if(cellItem->checkState() == Qt::Checked)
            str = str + "黨員";
        else
            str = str + "群眾";

        // 添加到編輯框作為一行
        // ui->textEdit->appendPlainText(str);
        ui->textEdit->append(str);
    }
}

當讀者點擊將表格讀入文本框後則可實現表格轉文本,如下圖所示;

完整案例下載

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

-Advertisement-
Play Games
更多相關文章
  • GoFrame Helper是一款適用於 Goland/IntelliJ IDEA Ultimate插件,它為 GoFrame 提供 ORM, Config, OpenApi 結構體標簽代碼輔助;Api, Controller, Service 代碼模板;監聽 Api, Logic 自動生成對應的 ... ...
  • 1. 賦值語句的特點 賦值語句創建對象的引用:賦值語句總是創建對象的引用,而不是複製對象。因此,Python中的變數更像是指針,而不是數據儲存區域。 變數在首次賦值時會被創建:因此不需要提前聲明變數。 變數在引用前必須先賦值:如果引用未賦值的變數會報錯 2. 賦值語句的形式 (1. 普通形式 >>> ...
  • 這篇筆記深入介紹了AOP(面向切麵編程),這個技術可以在代碼中以模塊化的方式實現橫切關註點。它解決了業務層代碼中存在的問題,如額外功能代碼的冗餘和每個方法都需要書寫一遍額外功能代碼的情況。 AOP在Spring中的實現主要依靠Aspect切麵、Advice通知和Pointcut切入點的組合。Advi... ...
  • ArrayList是一個使用List介面實現的Java類。顧名思義,Java ArrayList提供了動態數組的功能,其中數組的大小不是固定的。它實現了所有可選的列表操作,並允許所有元素,包括null。 ...
  • 原文: https://openaigptguide.com/ai-picture-generator/ 在人工智慧(AI)圖像生成技術的推動下,各類AI圖片生成網站如雨後春筍般涌現,為我們的日常生活提供了豐富多彩的視覺體驗。 AI圖片生成技術原理 人工智慧(AI)圖片生成技術原理是通過電腦程式使 ...
  • 背景及問題 如下程式所示: #include<iostream> class MyString { public: MyString() = default; MyString(const char* data) { printf("%s", "MyString Constructed!!\n"); ...
  • 引言 在ChatGpt火了這麼久,他的那種單字單字返回的格式可能讓很多朋友感到好奇,在之前我用c#寫了一個版本的,同時支持IAsyncEnumerable以及SSE,今天把之前寫的Java版本的也發出來,和大家一起學習,有不對的地方,歡迎各位大佬指正。 Code 我這邊用的是JDK21版本,可以看到 ...
  • 需求 有些應用每次啟動都需要用管理員許可權運行,比如Python註入dll時,編輯器或cmd就需要以管理員許可權運行,不然註入就會失敗。 這篇文章用編程怎麼修改配置實現打開某個軟體都是使用管理員運行,就不用每次都右鍵點擊以管理員身份運行此程式。主要是給小白配置,防止他忘了以管理員許可權運行,又跑過來問我為 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...