Qt?QTableWidget基本操作及使用
QTableWidget 是 Qt 中的表格組件類。在窗體上放置一個 QTableWidget 組件后,可以在 Property Editor 里對其進行屬性設置,雙擊這個組件,可以打開一個編輯器,對其 Colum、Row 和 Item 進行編輯。
一個 QTableWidget 組件的界面基本結(jié)構如圖 1 所示,這個表格設置為 6 行 5 列。
圖 1 一個 QTableWidget 表格的基本結(jié)構和工作區(qū)的行、列索引號
表格的第 1 行稱為行表頭,用于設置每一列的標題,第 1 列稱為列表頭,可以設置其標題,但一般使用缺省的標題,即為行號。行表頭和列表頭一般是不可編輯的。
除了行表頭和列表頭之外的表格區(qū)域是內(nèi)容區(qū),內(nèi)容區(qū)是規(guī)則的網(wǎng)格狀,如同一個二維數(shù)組,每個網(wǎng)格單元稱為一個單元格。每個單元格有一個行號、列號,圖 1 表示了行號、列號的變化規(guī)律。
在 QTableWidget 表格中,每一個單元格是一個 QTable Widgetltem 對象,可以設置文字內(nèi)容、字體、前景色、背景色、圖標,也可以設置編輯和顯示標記。每個單元格還可以存儲一個 QVariant 數(shù)據(jù),用于設置用戶自定義數(shù)據(jù)。
圖 2 實例 Samp4_9 的運行時界面
實例 samp4_9 以 QTableWidget 為主要組件,演示 QTableWidget 一些主要操作的實現(xiàn)。實例運行時的界面如圖 2 所示,該實例將演示以下功能的實現(xiàn)方法:
- 設置表格的列數(shù)和行數(shù),設置表頭的文字、格式等。
- 初始化表格數(shù)據(jù),設置一批實例數(shù)據(jù)填充到表格里。
- 插入行、添加行、刪除當前行的操作。
- 遍歷表格所有單元格,讀取表格內(nèi)容到一個 QPlainTextEdit 里,表格的一行數(shù)據(jù)作為一行文本。
- 表格上選擇的當前單元格變化時,在狀態(tài)欄顯示單元格存儲的信息。
界面設計與初始化
Samp4_9 的主窗體從 QMainWindow 繼承而來。在圖 2 所示的窗口上,一個 QTableWidget 組件和一個 QPlainTextEdit 組件組成上下分割布局 splitter。左側(cè)的按鈕都放在一個 QGroupBox 組件里,釆用 Grid 布局,然后將 groupBox 與 splitter 采用左右分割布局。這是一個典型的三區(qū)分割的布局。
在主窗口類 MainWindow 里自定義了一些變量和函數(shù),用于后面的代碼實現(xiàn),下面是在 MainWindow 的 private 部分自定義的變量和函數(shù):
private: //自定義單元格Type的類型,在創(chuàng)建單元格的item時使用 enum CellType{ctName=1000,ctSex,ctBirth,ctNation,ctPartyM,ctScore}; //各字段在表格中的列號 enum FieldColNum{colName=0,colSex,colBirth,colNation,colScore,colPartyM}; QLabel *labCellIndex; //狀態(tài)欄上用于顯示單元格的行號、列號 QLabel *labCellType; //狀態(tài)欄上用于顯示單元格的type QLabel *labStudID; //狀態(tài)欄上用于顯示學號 void createItemsARow(int rowNo,QString Name,QString Sex,QDate birth,QString Nation,bool isPM,int score) ; //為某一行創(chuàng)建 items
枚舉類型 CellType 是用來表示單元格類型的,在創(chuàng)建單元格時使用。枚舉類型 FieldColNum 用枚舉常量表示各字段在表格中的列號。
在 MainWindow 的構造函數(shù)里對界面進行初始化,代碼如下:
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); setCentralWidget(ui->splitterMain); //狀態(tài)欄初始化創(chuàng)建 labCellIndex = new QLabel ("當前單元格坐標:", this); labCellIndex->setMinimumWidth(250); labCellType=new QLabel ("當前單元格類型:",this); labCellType->setMinimumWidth(200); labStudID=new QLabel ("學生ID: ", this); labStudID->setMinimumWidth(200); ui->statusBar->addWidget (labCellIndex) ; //加到狀態(tài)欄 ui->statusBar->addWidget(labCellType); ui->statusBar->addWidget(labStudID); }
QTableWidget 基本操作
設置表頭
界面上的“設置表頭”按鈕實現(xiàn)對表頭的設置,其 clicked() 信號的槽函數(shù)代碼如下:
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); setCentralWidget(ui->splitterMain); //狀態(tài)欄初始化創(chuàng)建 labCellIndex = new QLabel ("當前單元格坐標:", this); labCellIndex->setMinimumWidth(250); labCellType=new QLabel ("當前單元格類型:",this); labCellType->setMinimumWidth(200); labStudID=new QLabel ("學生ID: ", this); labStudID->setMinimumWidth(200); ui->statusBar->addWidget (labCellIndex) ; //加到狀態(tài)欄 ui->statusBar->addWidget(labCellType); ui->statusBar->addWidget(labStudID); }
行表頭各列的文字標題由一個 QStringList 對象 headerText 初始化存儲,如果只是設置行表頭各列的標題,使用下面一行語句即可:
ui->tableInfo->setHorizontalHeaderLabels(headerText);
如果需要進行更加具體的格式設置,需要為行表頭的每個單元格創(chuàng)建一個 QTableWidgetItem 類型的變量,并進行相應設置。
在一個表格中,不管是表頭還是工作區(qū),每個單元格都是一個 QTableWidgetItem 對象。QTableWidgetItem 對象存儲了單元格的所有內(nèi)容,包括字標題、格式設置,以及關聯(lián)的數(shù)據(jù)。上面程序中的 for 循環(huán)遍歷 headerText 的每一行,用每一行的文字創(chuàng)建一個 QTableWidgetItem 對象 headerltem,然后設置 headerItem 的字體大小為 12、粗體、紅色,然后將 headerltem 賦給表頭的某一列:
ui->tableInfo->setHorizontalHeaderItern (i, headerItem);
初始化表格數(shù)據(jù)
界面上的“初始化表格數(shù)據(jù)”按鈕根據(jù)表格的行數(shù),生成數(shù)據(jù)填充表格,并為每個單元格生成 QTableWidgetItem 對象,設置相應屬性。下面是 btnlniData 的 clicked() 信號的槽函數(shù)代碼:
void MainWindow::on_btnIniData_clicked() { //初始化表格內(nèi)容 QString strName,strSex; bool isParty=false; QDate birth; birth.setDate(1980,4,7);//初始化一個日期 ui->tableInfo->clearContents();//只清除工作區(qū),不清除表頭 int Rows=ui->tableInfo->rowCount(); //數(shù)據(jù)區(qū)行數(shù), for (int i=0;i<Rows;i++) //數(shù)據(jù)區(qū)第1行的編號為0,所以范圍是0~rowCount()-1 { strName=QString::asprintf("學生%d",i); //學生姓名 if ((i % 2)==0) //分奇數(shù),偶數(shù)行設置性別,及其圖標 strSex="男"; else strSex="女"; createItemsARow(i, strName, strSex, birth,"漢族",isParty,70); //為某一行創(chuàng)建items birth=birth.addDays(20); //日期加20天 isParty =!isParty; } }
QTableWidget::clearContents() 函數(shù)清除表格數(shù)據(jù)區(qū)的所有內(nèi)容,但是不清除表頭。
QTableWidget::rowCount() 函數(shù)返回表格數(shù)據(jù)區(qū)的行數(shù)。
在 for 循環(huán)里為每一行生成需要顯示的數(shù)據(jù),然后調(diào)用自定義函數(shù) createItemsARow(),為表格一行的各個單元格生成 QTableWidgetItem 對象。
createItemsARow() 是在窗體類里自定義的函數(shù),其實現(xiàn)代碼如下:
void MainWindow::createItemsARow(int rowNo,QString Name,QString Sex,QDate birth,QString Nation,bool isPM,int score) { //為一行的單元格創(chuàng)建 Items QTableWidgetItem *item; QString str; uint StudID=201605000; //學號基數(shù) //姓名 //新建一個Item,設置單元格type為自定義的MainWindow::ctName item=new QTableWidgetItem(Name,MainWindow::ctName); item->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); //文本對齊格式 StudID +=rowNo; //學號=基數(shù)+ 行號 item->setData(Qt::UserRole,QVariant(StudID)); //設置studID為data ui->tableInfo->setItem(rowNo,MainWindow::colName,item); //為單元格設置Item //性別 QIcon icon; if (Sex=="男") icon.addFile(":/images/icons/boy.ico"); else icon.addFile(":/images/icons/girl.ico"); item=new QTableWidgetItem(Sex,MainWindow::ctSex); //新建一個Item,設置單元格type為自定義的 MainWindow::ctSex item->setIcon(icon); item->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);//為單元格設置Item ui->tableInfo->setItem(rowNo,MainWindow::colSex,item);//為單元格設置Item //出生日期 str=birth.toString("yyyy-MM-dd"); //日期轉(zhuǎn)換為字符串 item=new QTableWidgetItem(str,MainWindow::ctBirth);//新建一個Item,設置單元格type為自定義的 MainWindow::ctBirth item->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter); //文本對齊格式 ui->tableInfo->setItem(rowNo,MainWindow::colBirth,item);//為單元格設置Item //民族 item=new QTableWidgetItem(Nation,MainWindow::ctNation); //新建一個Item,設置單元格type為自定義的 MainWindow::ctNation item->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);//文本對齊格式 ui->tableInfo->setItem(rowNo,MainWindow::colNation,item);//為單元格設置Item //是否黨員 item=new QTableWidgetItem("黨員",MainWindow::ctPartyM);//新建一個Item,設置單元格type為自定義的 MainWindow::ctPartyM item->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);//文本對齊格式 if (isPM) item->setCheckState(Qt::Checked); else item->setCheckState(Qt::Unchecked); item->setBackgroundColor(Qt::yellow);//Qt::green lightGray yellow ui->tableInfo->setItem(rowNo,MainWindow::colPartyM,item);//為單元格設置Item //分數(shù) str.setNum(score); item=new QTableWidgetItem(str,MainWindow::ctScore);//新建一個Item,設置單元格type為自定義的 MainWindow::ctPartyM item->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);//文本對齊格式 ui->tableInfo->setItem(rowNo,MainWindow::colScore,item);//為單元格設置Item }
該表格的每一行有5列,為每一個單元格都創(chuàng)建一個 QTableWidgetItem 類型的變量 item,并做相應的設置。
創(chuàng)建 QTableWidgetItem 使用的構造函數(shù)的原型為:
QTableWidgetItem::QTableWidgetItem (const QString &text, int type = Type)
其中,第一個參數(shù)作為單元格的顯示文字,第二個參數(shù)作為節(jié)點的類型。
例如創(chuàng)建“姓名”單元格對象時的語句是:
cellItem=new QtableWidgetItem(Name,MainWindow::ctName);
其中,MainWindow::ctName 是定義的枚舉類型 CellType 的一個常量值。
“姓名”單元格還調(diào)用 setData() 函數(shù)設置了一個自定義的數(shù)據(jù),存儲的是學生 ID。
cellItem->setData(Qt::UserRole,QVariant(StudID));
這個自定義數(shù)據(jù)是不顯示在界面上的,但是與單元格相關聯(lián)。
QTableWidgetItem 有一些函數(shù)對單元格進行屬性設置,如下:
- setTextAlignment (int alignment):設置文字對齊方式。
- setBackground(const QBrush &brush):設置單元格背景顏色。
- setForeground(const QBrush &brush):設置單元格前景色。
- setIcon(const QIcon &icon):為單元格設置一個顯不圖標。
- setFont(const QFont &font):為單元格顯示文字設置字體。
- setCheckState(Qt::CheckState state):設置單元格勾選狀態(tài),單元格里出現(xiàn)一個QCheckBox組件。
- setFlags(Qt::ItemFlags flags):設置單元格的一些屬性標記。
設置好 item 的各種屬性之后,用 QTableWidget 的 setItem 函數(shù)將 item 設置為單元格的項,例如:
ui->tableInfo->setItem(rowNo,MainWindow::colName,item);
其中,MainWindow::colName 是定義的枚舉類型 FieldColNum 的一個常量值。
這樣初始化設置后,就可以得到如圖 2 所示的運行時的表格內(nèi)容。表格里并沒有顯示學號,學號是“姓名”單元格的關聯(lián)數(shù)據(jù)。
獲得當前單元格數(shù)據(jù)
當鼠標在表格上單擊單元格時,被選中的單元格是當前單元格。通過 QTableWidget 的 currentColumn() 和 currentRow() 可以獲得當前單元格的列編號和行編號。
當前單元格發(fā)生切換時,會發(fā)射 currentCellChanged() 信號和 currentItemChanged() 信號,兩個信號都可以利用,只是傳遞的參數(shù)不同。
對 currentCellChanged() 信號編寫槽函數(shù),用于獲取當前單元格的數(shù)據(jù),以及當前行的學生的學號信息,代碼如下:
void MainWindow::on_tableInfo_currentCellChanged(int currentRow, int currentColumn, int previousRow, int previousColumn) {//當前選擇單元格發(fā)生變化時的響應 Q_UNUSED(previousRow); Q_UNUSED(previousColumn); QTableWidgetItem* item=ui->tableInfo->item(currentRow,currentColumn); //獲取單元格的 Item if (item==NULL) return; labCellIndex->setText(QString::asprintf("當前單元格坐標:%d 行,%d 列",currentRow,currentColumn)); int cellType=item->type();//獲取單元格的類型 labCellType->setText(QString::asprintf("當前單元格類型:%d",cellType)); item=ui->tableInfo->item(currentRow,MainWindow::colName); //取當前行第1列的單元格的 item int ID=item->data(Qt::UserRole).toInt();//讀取用戶自定義數(shù)據(jù) labStudID->setText(QString::asprintf("學生ID:%d",ID));//學生ID }
在 currentCellChanged() 信號中,傳遞的參數(shù) currentRow 和 currentColumn 表示當前單元格的行號和列號,通過這兩個編號可以得到單元格的 QTableWidgetltem 對象 item。
獲得 item 之后,通過 type() 函數(shù)得到單元格的類型參數(shù),這個類型就是為單元格創(chuàng)建 QTableWidgetItem 對象時傳遞的類型參數(shù)。
再獲取同一行的“姓名”單元格的項,用data()函數(shù)提取自定義數(shù)據(jù),也就是創(chuàng)建單元格時存儲的學生 ID。
插入、添加、刪除行
QTableWidget 處理行操作的函數(shù)如下:
- insertRow(int row):在行號為row的行前面插入一行,如果row等于或大于總行數(shù),則在表格最后添加一行。insertRow()函數(shù)只是插入一個空行,不會為單元格創(chuàng)建QTableWidgetItem對象,需要手工為單元格創(chuàng)建。
- removeRow(int row):刪除行號為 row 的行。
下面是界面上“插入行” “添加行”“刪除當前行”按鈕的響應代碼。在插入行之后,會調(diào)用 createItemsARow() 函數(shù),為新創(chuàng)建的空行的各單元格構造 QTableWidgetItem 對象:
void MainWindow::on_btnInsertRow_clicked() { //插入一行 //int curRow; int curRow=ui->tableInfo->currentRow();//當前行號 ui->tableInfo->insertRow(curRow); //插入一行,但不會自動為單元格創(chuàng)建item createItemsARow(curRow, "新學生", "男", QDate::fromString("1990-1-1","yyyy-M-d"),"苗族",true,60 ); //為某一行創(chuàng)建items } void MainWindow::on_btnAppendRow_clicked() { //添加一行 //int curRow; int curRow=ui->tableInfo->rowCount();//當前行號 ui->tableInfo->insertRow(curRow);//在表格尾部添加一行 createItemsARow(curRow, "新生", "女", QDate::fromString("2000-1-1","yyyy-M-d"),"滿族",false,50 ); //為某一行創(chuàng)建items } void MainWindow::on_btnDelCurRow_clicked() {//刪除當前行及其items //int curRow; int curRow=ui->tableInfo->currentRow();//當前行號 ui->tableInfo->removeRow(curRow); //刪除當前行及其items }
自動調(diào)整行高和列寬
QTableWidget 有幾個函數(shù)自動調(diào)整表格的行高和列寬,分別如下:
- resizeColumnsToContents():自動調(diào)整所有列的寬度,以適應其內(nèi)容。
- resizeColumnToContents(int column):自動調(diào)整列號為 co/www 的列的寬度。
- resizeRowsToContents():自動調(diào)整所有行的高度,以適應其內(nèi)容。
- resizeRowToContents(int row):自動調(diào)整行號為 raw 的行的高度。
這幾個函數(shù)實際上是 QTableWidget 的父類 QTableView 的函數(shù)。
其他屬性控制
設置表格內(nèi)容是否可編輯:QTableWidget 的 EditTriggers 屬性表示是否可編輯,以及進入編輯狀態(tài)的方式。界面上的"表格可編輯"復選框的槽函數(shù)代碼為:
void MainWindow::on_chkBoxTabEditable_clicked(bool checked) { //設置編輯模式 if (checked) //雙擊或獲取焦點后單擊,進入編輯狀態(tài) ui->tableInfo->setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::SelectedClicked); else ui->tableInfo->setEditTriggers(QAbstractItemView::NoEditTriggers); //不允許編輯 }
設置行表頭、列表頭是否顯示:horizontalHeader()獲取行表頭,verticalHeader()獲取列表頭,然后可設置其可見性。
void MainWindow::on_chkBoxHeaderH_clicked(bool checked) { //是否顯示水平表頭 ui->tableInfo->horizontalHeader()->setVisible(checked); } void MainWindow::on_chkBoxHeaderV_clicked(bool checked) { //是否顯示垂直表頭 ui->tableInfo->verticalHeader()->setVisible(checked); }
間隔行底色:setAltematingRowColors() 函數(shù)可以設置表格的行是否用交替底色顯示,若為交替底色,則間隔的一行會用灰色作為底色。具體底色的設置需要用 styleSheet,在后續(xù)章節(jié)會有介紹。
void MainWindow::on_chkBoxRowColor_clicked(bool checked) { ui->tableInfo->setAlternatingRowColors(checked); }
選擇模式:setSelectionBehavior() 函數(shù)可以設置選擇方式為單元格選擇,還是行選擇:
void MainWindow::on_rBtnSelectItem_clicked() {//選擇行為:單元格選擇 ui->tableInfo->setSelectionBehavior(QAbstractltemView::Selectltems); } void MainWindow::on_rBtnSelectRow_clicked() {//選擇行為:行選擇 ui->tableInfo->setSelectionBehavior(QAbstractltemView::SelectRows); }
遍歷表格讀取數(shù)據(jù)
“讀取表格內(nèi)容到文本”按鈕演示了將表格數(shù)據(jù)區(qū)的內(nèi)容全部讀出的方法,它將每個單元格的文字讀出,同一行的單元格的文字用空格分隔開,作為文本的一行,然后將這行文字作為文本編輯器的一行內(nèi)容,代碼如下:
void MainWindow::on_btnReadToEdit_clicked() {//將 QTableWidget的所有行的內(nèi)容提取字符串,顯示在QPlainTextEdit里 QString str; QTableWidgetItem *cellItem; ui->textEdit->clear(); //文本編輯器清空 for (int i=0;i<ui->tableInfo->rowCount();i++) //逐行處理 { str=QString::asprintf("第 %d 行: ",i+1); for (int j=0;j<ui->tableInfo->columnCount()-1;j++) //逐列處理,但最后一列是check型,單獨處理 { cellItem=ui->tableInfo->item(i,j); //獲取單元格的item str=str+cellItem->text()+" "; //字符串連接 } cellItem=ui->tableInfo->item(i,colPartyM); //最后一列,黨員 if (cellItem->checkState()==Qt::Checked) //根據(jù)check狀態(tài)顯示文字 str=str+"黨員"; else str=str+"群眾"; ui->textEdit->appendPlainText(str); //添加到編輯框作為一行 } }
到此這篇關于Qt QTableWidget基本操作及使用的文章就介紹到這了,更多相關Qt QTableWidget內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
C語言完美實現(xiàn)動態(tài)數(shù)組代碼分享
本文給大家分享的是一則使用C語言實現(xiàn)動態(tài)數(shù)組的代碼,完美解決內(nèi)存溢出以及內(nèi)存回收問題,有需要的小伙伴可以參考下。2016-02-02