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
設置表頭。
以下是關於該代碼的一些解釋:
setHorizontalHeaderLabels
方法用於設置水平表頭的標簽。在這裡,headerText_Row
是一個包含列標簽的字元串列表,每個字元串對應一個表格列。- 如果需要設置垂直表頭,可以使用
setVerticalHeaderLabels
方法,將一個包含行標簽的字元串列表傳遞給它。 - 可以通過迴圈設置表頭的每個單元格的屬性。在這裡,使用了迴圈遍歷列並創建一個
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
表格的行數。
以下是關於該代碼的一些解釋:
- 通過
ui->spinBox->value()
讀取QSpinBox
中的值,即用戶選擇的數量。 - 使用
setRowCount
方法將讀取到的數量設置為表格的行數。 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
。
以下是對該代碼的一些解釋:
- 姓名(Name):
- 使用
QTableWidgetItem
創建一個單元格,並將其類型設置為自定義的MainWindow::ctName
。 - 設置文本對齊格式為水平居中和垂直居中。
- 使用
setData
方法將學號(StudID)設置為單元格的數據。 - 將
QTableWidgetItem
添加到表格的指定位置。
- 使用
- 性別(Sex):
- 使用
QTableWidgetItem
創建一個單元格,並將其類型設置為自定義的MainWindow::ctSex
。 - 根據性別設置對應的圖標。
- 設置文本對齊格式為水平居中和垂直居中。
- 將
QTableWidgetItem
添加到表格的指定位置。
- 使用
- 出生日期(birth):
- 使用
QTableWidgetItem
創建一個單元格,並將其類型設置為自定義的MainWindow::ctBirth
。 - 將日期轉換為字元串,並設置為單元格的文本。
- 設置文本對齊格式為左對齊和垂直居中。
- 將
QTableWidgetItem
添加到表格的指定位置。
- 使用
- 民族(Nation):
- 使用
QTableWidgetItem
創建一個單元格,並將其類型設置為自定義的MainWindow::ctNation
。 - 設置文本對齊格式為水平居中和垂直居中。
- 將
QTableWidgetItem
添加到表格的指定位置。
- 使用
- 是否黨員(isPM):
- 使用
QTableWidgetItem
創建一個單元格,並將其類型設置為自定義的MainWindow::ctPartyM
。 - 根據是否黨員設置對應的覆選框狀態。
- 設置文本對齊格式為水平居中和垂直居中。
- 設置背景顏色為黃色。
- 將
QTableWidgetItem
添加到表格的指定位置。
- 使用
- 分數(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
函數,並傳入數據,至此就可以實現創建一行,通過迴圈的方式則可以實現多行的創建。
如下代碼用於初始化表格元素,通過迴圈為每一行添加學生數據。
以下是代碼的主要解釋:
- 清除內容:
- 使用
ui->tableWidget->clearContents()
清除工作區中的內容,但不清除表格結構。
- 使用
- 迴圈添加行數據:
- 獲取表格的總行數,即數據區的行數。
- 使用迴圈為每一行添加學生數據。
- 使用
QString::asprintf
格式化字元串設置學生姓名。 - 根據行號的奇偶性設置性別,同時設置對應的圖標。
- 調用
createItemsARow
方法為某一行創建各個單元格的QTableWidgetItem
。
- 日期處理:
- 初始日期設定為1997年10月7日。
- 迴圈中,每次添加行後,將日期加20天。
- 黨員標誌處理:
- 使用布爾變數
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
中的數據讀入文本框的功能。
以下是代碼的主要解釋:
- 清空文本框:
- 使用
ui->textEdit->clear()
清空文本框內容。
- 使用
- 迴圈遍歷表格行:
- 通過
ui->tableWidget->rowCount()
獲取表格的行數,進行迴圈遍歷。
- 通過
- 逐列處理數據:
- 使用內部迴圈
for (int j=0; j<ui->tableWidget->columnCount()-1; j++)
處理每一列的數據,最後一列是黨員狀態,需要單獨處理。 - 獲取每個單元格的
QTableWidgetItem
。 - 使用
cellItem->text()
獲取單元格的文本內容。 - 將每列的文本內容連接為一行字元串。
- 使用內部迴圈
- 黨員狀態處理:
- 獲取最後一列(黨員狀態列)的
QTableWidgetItem
。 - 使用
cellItem->checkState()
判斷覆選框的狀態,根據狀態判斷是否為黨員。
- 獲取最後一列(黨員狀態列)的
- 添加到文本框:
- 將每一行的字元串添加到文本框中,使用
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);
}
}
當讀者點擊將表格讀入文本框後則可實現表格轉文本,如下圖所示;
本博客所有文章除特別聲明外,均採用 BY-NC-SA 許可協議。轉載請註明出處!