Qt——QTableWidget 與 QTableView開發實踐【不負此行!】

流程圖

繼承
環境
QTableWidget
QTableView
區別

環境

開發環境
Windows7操作系統
Qt 5.8C++GUI框架
MinGW 5.3.0 32bit編譯器
Qt Creator 4.2.1編輯器

QTableWidget

實現基本功能

參考:
Qt QTableWidget的用法詳解
Qt QTableWidget用法總結

設置不可編輯

整個表格不可編輯

函數原型:void setEditTriggers(EditTriggers triggers);
頭文件:qabstractitemview.h
說明:參數一表示填入EditTrigger枚舉

ui->aTabWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);

在這裏插入圖片描述

若你沒有ui界面,想用代碼實現,也是可以的:替代這段“ui->aTabWidget->”僞代碼即可
在這裏插入圖片描述

    QTableWidget *t = new QTableWidget(this);
    t->setEditTriggers(QAbstractItemView::NoEditTriggers);

PS:

  • 定義的QTableWidget對象一定要是“指針變量”
  • new的時候,把this作爲父窗口,表格纔會出現在窗口中

隱藏表頭

其實就是:設置是否 可見 或者 設置 隱藏
PS:

在這裏插入圖片描述

隱藏列表頭

horizontal Header水平的 頭部——列表頭

函數原型 頭文件
QHeaderView *horizontalHeader() const; qtableview.h
void setVisible(bool v) Q_DECL_OVERRIDE; qheaderview.h
void hide(); qwidget.h
void setHidden(bool hidden); qwidget.h
ui->aTabWidget->horizontalHeader()->setVisible(false);

或

ui->aTabWidget->horizontalHeader()->hide();

或

ui->aTabWidget->horizontalHeader()->setHidden(true);

隱藏行表頭

vertical Header垂直的 頭部——行表頭

函數原型:QHeaderView *verticalHeader() const;
頭文件:qtableview.h

ui->aTabWidget->verticalHeader()->setVisible(false);

或

ui->aTabWidget->verticalHeader()->hide();

PS:隱藏行表頭與隱藏列表頭差不多,大同小異。

設置列寬、行高

沒有列高、行寬的概念(即使有,也是不對的,請準守規範),也沒有這樣的函數;
所以是設置列寬行高

在這裏插入圖片描述

設置列寬

函數原型:void setColumnWidth(int column, int width);
頭文件:(居然是在這裏?請看PS:解釋)qtableview.h
說明:參數一表示列的 下標,參數二表示 設置指定列的寬度(單位應該是像素)。

ui->aTabWidget->setColumnWidth(3, 140);

或

ui->aTabWidget->QTableWidget::setColumnWidth(3, 140);
[自動找QTableView::setColumnWidth( , )函數]

PS:

實際上
setColumnWidth函數用的不是QTableWidget裏的而是QTableView裏的!
在官方文檔中
可知,QTableWidget類裏並沒有該函數,還有這個setRowHeight函數,它也沒有!!!
爲什麼會這樣?
因爲QTableWidget繼承了QTableView,可以理所當然地使用父類的函數!

設置行高

函數原型:void setRowHeight(int row, int height);
頭文件:qtableview.h
說明:參數一表示行的 下標,參數二表示 設置指定行的高度。

    ui->aTabWidget->setRowHeight(0,35);

設置表頭字體居中

其實,表頭字體默認(水平或垂直方向的)居中!
AlignmentFlag枚舉的屬性定義,如圖所示:

在這裏插入圖片描述

PS:
最後一個屬性:
AlignCenter = AlignVCenter | AlignHCenter
表示:水平及垂直方向都居中

設置列表頭字體居中

列表頭字體默認水平方向居中,只能設置:AlignLeft、AlignRight、AlignHCenter等屬性。若執意設置垂直方向的屬性,顯示情況:相當於文本設置AlignLeft

    ui->aTabWidget->horizontalHeader()->setDefaultAlignment(Qt::AlignHCenter);

設置行表頭字體居中

行表頭字體默認垂直方向居中,只能設置:AlignTop、AlignBottom、AlignVCenter等屬性。若執意設置水平方向的屬性,顯示情況:相當於文本設置AlignTop

ui->aTabWidget->verticalHeader()->setDefaultAlignment(Qt::AlignVCenter);

其他

參考:

  1. QT任意組件的(文字)對齊方式——alignment 屬性setAlignment()
  2. enum Qt::AlignmentFlag——Qt文檔

e.g:
若設置水平居右 或 垂直底部,換屬性即可:

ui->aTabWidget->horizontalHeader()->setDefaultAlignment(Qt::AlignRight);
ui->aTabWidget->verticalHeader()->setDefaultAlignment(Qt::AlignBottom);

合併單元格

函數原型:void setSpan(int row, int column, int rowSpan, int columnSpan);
頭文件:qtableview.h
說明:參數一與參數二都填入 下標;參數一表示單元格的行,參數二表示單元格的列,參數三表示合併行數,參數表示合併列數。

ui->aTabWidget->setSpan(0,1,2,1);
ui->aTabWidget->setSpan(0,2,2,1);

在這裏插入圖片描述

參考:
QTableWidget表格合併若干問題及解決方法

延伸:合併表頭

因爲沒有這方面需求,並沒有測試,在找合併單元格時不小心看到的文章:

QT QTableView QTableWidget 複雜表頭(多行表頭) 、(凍結、固定特定的行)
QT+qtablewidget自定義表頭【合併單元格】

清空表格內容

函數原型:void clearContents();
頭文件:qtablewidget.h

ui->aTabWidget->clearContents();

QTableWidgetItem

將值寫入表格指定單元格中

函數原型:void setItem(int row, int column, QTableWidgetItem *item);
頭文件:qtablewidget.h
說明:參數一與參數二都填入 下標;參數一表示單元格的行,參數二表示單元格的列,參數三表示傳入指定Value的QTableWidgetItem 指針變量。

QTableWidgetItem *item = new QTableWidgetItem(value);
ui->aTabWidget->setItem(0,0,item);

設置值居中(水平、垂直)

函數原型:inline void setTextAlignment(int alignment)
{ setData(Qt::TextAlignmentRole, alignment); }
頭文件:qtablewidget.h

有了上面水平方向垂直方向 居中代碼基礎,在此,容易看得懂這裏的代碼:

QTableWidgetItem *item = new QTableWidgetItem(value);
item->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
ui->aTabWidget->setItem(0,0,item);

設置字體顏色

函數原型:inline void setForeground(const QBrush &brush)
{ setData(Qt::ForegroundRole, brush); }
頭文件:qtablewidget.h

QTableWidgetItem *item = new QTableWidgetItem(value);
//把表格的item的文字顏色設置爲紅色
item->setForeground(QBrush(QColor(255, 0, 0)));
ui->aTabWidget->setItem(0,0,item);

參考:QT控制選中item的文字顏色(Highlighted Text)

獲取單元格內容

函數原型:QTableWidgetItem *item(int row, int column) const;
頭文件:qtablewidget.h
說明:參數一與參數二都填入 下標;參數一表示單元格的行,參數二表示單元格的列。
函數原型:inline QString text() const
{ return data(Qt::DisplayRole).toString(); }
頭文件:qtablewidget.h

QString value = ui->aTabWidget->item(row,column)->text();

單元格設置複選框

參考:

  1. Qt — tableWidget插入複選框
  2. QTableWidget中添加checkbox,並相應觸發函數

函數原型: inline void setCheckState(Qt::CheckState state)
{ setData(Qt::CheckStateRole, state); }
頭文件:qtablewidget.h
說明:參數一表示填入CheckState枚舉的屬性。

在這裏插入圖片描述

QTableWidgetItem *check=new QTableWidgetItem;
check->setCheckState (Qt::Checked);//或Unchecked
ui->aTabWidget->setItem(0,2,check); //插入複選框

QTableView

  • QTableView Class
    你會發現,與QTableWidget有些出入,因此,重複的說明我就不多說了,沒有提到的,我再附上說明,若還有不懂的地方,請在評論區告訴我 或者 私聊我

前提:創建了xxxUI界面,在裏面設置了aTabView

實現基本功能

參考:Qt GUI圖形圖像開發之Qt表格控件QTableView簡單使用方法及QTableView與QTableWidget區別

設置不可編輯

整個表格不可編輯

ui->aTabView->setEditTriggers(QAbstractItemView::NoEditTriggers);

某行或某列只讀

網上查到的代碼1,還真管用!

因爲qt庫中沒有設置指定列或行只讀的函數,需要繼承QItemDelegate自定義一個只讀委託類,實現“指定列或行只讀

在已有的頭文件lookoverpartdata.h中加上這些代碼:【然後可以在其他類的cpp或者lookoverpartdata.cpp中定義並使用】

#include <QItemDelegate>

class ReadOnlyDelegate: public QItemDelegate
{

public:
    ReadOnlyDelegate(QWidget *parent = NULL):QItemDelegate(parent){}

    QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
const QModelIndex &index) const override //final
    {
        Q_UNUSED(parent)
        Q_UNUSED(option)
        Q_UNUSED(index)
        return NULL;
    }
};

在這裏插入圖片描述

某列不可編輯

函數原型:void setItemDelegateForColumn(int column, QAbstractItemDelegate *delegate);
頭文件:qabstractitemview.h
說明:參數一表示列的 下標,參數二表示 QAbstractItemDelegate 指針變量。

ReadOnlyDelegate* readOnlyDelegate = new ReadOnlyDelegate();
ui->aTabView->setItemDelegateForColumn(2, readOnlyDelegate); //設置某列只讀
某行不可編輯

函數原型:void setItemDelegateForRow(int row, QAbstractItemDelegate *delegate);
頭文件:qabstractitemview.h
說明:參數一表示行的 下標,參數二表示 QAbstractItemDelegate 指針變量。

ReadOnlyDelegate* readOnlyDelegate = new ReadOnlyDelegate();
ui->aTabView->setItemDelegateForRow(0, readOnlyDelegate);    //設置某行只讀

隱藏表頭

隱藏列表頭

ui->aTabView->horizontalHeader()->setVisible(false);

或

ui->aTabView->horizontalHeader()->hide();

或

ui->aTabView->horizontalHeader()->setHidden(true);

隱藏行表頭

ui->aTabView->verticalHeader()->setVisible(false);

或

ui->aTabView->verticalHeader()->hide();

固定、自適應寬度或高度

枚舉常量 描述
QHeaderView::Interactive 0 用戶可以重新調整表頭的大小,也可以使用resizeSection()重新調整表頭的大小。目前我的TabView默認這個常量。
QHeaderView::Stretch 1 表頭將會調整單元格到可得的空間。用戶或者程序員通過代碼都不能改變它的大小
QHeaderView::Fixed 2 用戶不可以重新調整表頭的大小,只可以使用resizeSection()重新調整表頭的大小
QHeaderView::ResizeToContents 3 表頭將自動根據整個行或者列的內容去調整表頭單元格到最佳的大小。用戶或者程序員通過代碼都不能改變它的大小

在這裏插入圖片描述

固定或自適應寬度

函數原型:void setSectionResizeMode(ResizeMode2 mode);
頭文件:qheaderview.h
說明:horizontalHeader()->指向該函數,表示 水平表頭/列表頭不可伸縮寬度。

固定寬度:

#include <QHeaderView>

ui->aTabView->horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed);

PS:
固定寬度,在列表頭,就不會出現“伸縮”指針/光標(如圖所示)了。

在這裏插入圖片描述

自適應寬度:

#include <QHeaderView>

ui->aTabView->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);

執行後的模樣:

在這裏插入圖片描述

填值後:

在這裏插入圖片描述

看得出,起到了 自適應 作用。

PS:

  • 當寫入單元格的內容出現過長時會自適應列寬加大,因此會出現底部滾動條。
  • 寬度根據內容變化,高度可以自己鼠標移動“伸縮”指針/光標來調整

固定或自適應高度

函數原型:void setSectionResizeMode(ResizeMode2 mode);
頭文件:qheaderview.h
說明:verticalHeader()->指向該函數,表示 垂直表頭/行表頭不可伸縮高度。

固定高度:

#include <QHeaderView>

ui->aTabView->verticalHeader()->setSectionResizeMode(QHeaderView::Fixed);

PS:
固定高度,在行表頭,就不會出現“伸縮”指針/光標了。

自適應高度:

#include <QHeaderView>

ui->aTabView->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);

執行後的模樣:

在這裏插入圖片描述

填值後:

在這裏插入圖片描述

看得出,起到了 自適應 作用,但要包含中文的內容,纔可以自動將多餘的值換行

PS:

  • 高度根據內容變化,寬度可以自己鼠標“伸縮”指針/光標來調整。
  • 若寫了該代碼,還寫了自適應寬度代碼,效果:只能自適應寬度,不能自適應高度,而且寬度與高度都不能自己鼠標“伸縮”指針/光標來調整。

設置表格背景網格線

參考:Qt之QTableView的使用

函數原型:void setShowGrid(bool show);
頭文件:qtableview.h
說明:參數一表示背景網格線是否設置,true爲顯示,false爲取消。
函數原型:void setGridStyle(Qt::PenStyle style);
頭文件:qtableview.h
說明:參數一表示網格背景畫筆設置,填入Qt::PenStyle枚舉中的值

在這裏插入圖片描述

常量 描述
Qt::NoPen 0 無線
Qt::SolidLine 1 實線(默認)
Qt::DashLine 2 虛線
Qt::DotLine 3 點線
Qt::DashDotLine 4 虛點線
Qt::DashDotDotLine 5 虛點點線
Qt::CustomDashLine 6 自定義虛線
ui->aTabView->setShowGrid(true);
ui->aTabView->setGridStyle(Qt::DotLine);

DotLine點線:

在這裏插入圖片描述

SolidLine實線:

在這裏插入圖片描述

DashDotDotLine虛點點線:

在這裏插入圖片描述

QStandardItemModel

自定義列表頭內容

默認的表頭都是按數字順序自增的"1 2 3";若想設置表頭爲自己指定的格式,這時要用上QStandardItemModel了;表頭內容位置默認居中。

在這裏插入圖片描述

函數原型:void setHorizontalHeaderLabels(const QStringList &labels);
頭文件:qstandarditemmodel.h
說明:參數一表示傳入QStringList對象變量。

#include <QStandardItem>

QStandardItemModel* model = new QStandardItemModel();
QStringList labels = QObject::trUtf8("頻率,功率,誤差").simplified().split(",");
model->setHorizontalHeaderLabels(labels);//設置自定義表頭

在這裏插入圖片描述

設置單元格內容

函數原型:void setItem(int row, int column, QStandardItem *item);
頭文件:qstandarditemmodel.h
說明:參數一與參數二都填入 下標;參數一表示單元格的行,參數二表示單元格的列,參數三表示有值的QStandardItem 指針變量。
函數原型:void setModel(QAbstractItemModel *model) Q_DECL_OVERRIDE;
頭文件:qtableview.h
說明:參數一表示填入QStandardItemModel結構建模對象,進行數據源綁定,將模式加入TabView表中。
函數原型:void show();
頭文件:qwidget.h

#include <QStandardItem>
QStandardItemModel* model = new QStandardItemModel();
QStandardItem* item = new QStandardItem(QString("%1").arg("好"));
model->setItem(0,0,item);

//該行,使用一次即可(進行表與模型的綁定),若後續更改了item,
//可在model->setItem(0,0,item);處作結尾,並且程序不會停止更新更改過的表格內容。
ui->aTabView->setModel(model);
//可以註釋,因爲在我的UI中已存在該表格,若用代碼創建TabView則必須加上該行代碼,使用一次即可。
ui->aTabView->show();

設置值居中(水平、垂直)

函數原型:inline void QStandardItem::setTextAlignment(Qt::Alignment atextAlignment)
{ setData(int(atextAlignment), Qt::TextAlignmentRole); }
頭文件:qstandarditemmodel.h

有了上面水平方向垂直方向 居中代碼基礎,在此,容易看得懂這裏的代碼:

QStandardItemModel* model = new QStandardItemModel();
QStandardItem* item = new QStandardItem(QString("%1").arg("好"));
item->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
model->setItem(0,0,item);
ui->aTabView->setModel(model);

設置行、列數量

函數原型:void setRowCount(int rows);
頭文件:qstandarditemmodel.h
說明:參數一表示行數量。
函數原型:void setColumnCount(int columns);
頭文件:qstandarditemmodel.h
說明:參數一表示列數量。

#include <QStandardItem>.h中定義:QStandardItemModel* model;.cpp中使用:
model = new QStandardItemModel();
model->setColumnCount(3);
model->setRowCount(6);

獲取單元格內容

函數原型:QStandardItem *item(int row, int column = 0) const;
頭文件:qstandarditemmodel.h
說明:參數一表示行的 下標,參數二表示列的 下標
函數原型:inline QString text() const {
return qvariant_cast(data(Qt::DisplayRole));
}
頭文件:qstandarditemmodel.h

#include <QStandardItem>.h中定義:QStandardItemModel* model;.cpp中使用:
model = new QStandardItemModel();
QStandardItem* item = model->item(row,column);
QString value = item->text();

清空表格內容

前提1:
在UI界面的menu中加了“清除”功能,並在相應構造函數,綁定了“信號與槽”:

connect(ui->clearAction,SIGNAL(triggered()),this,SLOT(clearXxx()));

在這裏插入圖片描述

問:
在clearXxx()槽函數中,怎麼寫代碼呢?————說白了,怎麼清空內容呢?
答:
有兩種方法:一種是使用QStandardItemModel的removeColumns或removeRows函數;一種是將單元格進行初始化。

前提2:【原來的模樣】

在這裏插入圖片描述

使用QStandardItemModel
  1. 保住行表頭
    函數原型:bool removeColumns(int column, int count, const QModelIndex &parent = QModelIndex()) Q_DECL_OVERRIDE;
    頭文件:qstandarditemmodel.h
    說明:參數一表示列的 下標,參數二表示 移除指定數量的列數,連(無論是水平方向還是垂直方向)滾動條都會移除。
#include <QStandardItem>.h中定義:QStandardItemModel* model;.cpp中使用:
model->removeColumns(0,model->columnCount());

在這裏插入圖片描述

  1. 保住列表頭
    函數原型:bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) Q_DECL_OVERRIDE;
    頭文件:qstandarditemmodel.h
    說明:參數一表示行的 下標,參數二表示 移除指定數量的行數,連(無論是水平方向還是垂直方向)滾動條都會移除。
#include <QStandardItem>.h中定義:QStandardItemModel* model;.cpp中使用:
model->removeRows(0,model->rowCount());

在這裏插入圖片描述

model->removeColumns(0,2);//從0開始,移除2列

在這裏插入圖片描述

參考:
Qt QTableView 如何清理列表裏的數據

初始化

填值後的模樣:

在這裏插入圖片描述

初始化後:【變回原樣】

在這裏插入圖片描述

啓用列排序

函數原型:void setSortingEnabled(bool enable);
頭文件:qtableview.h
說明:參數一表示傳入bool值,若爲true,就會開啓列排序功能,當前列的數字從高到低 ;默認不排序爲false,不啓用排序功能。

ui->aTabView->setSortingEnabled(true);

原來的排序(用for輸入值,看起來是由低至高,其實並沒有排序):
在這裏插入圖片描述
加入代碼後,啓用排序功能:
在這裏插入圖片描述

PS:
必須放在ui->aTabView->setModel(model);後面!!!
否則無效果!!!
【但我印象中,小Demo測試時,無論前後都是有效的。不知道爲何現在,項目寫好了,放開該代碼,必須放入其後面,才起到作用!】

設置列寬、行高

前提:
必須放在ui->aTabView->setModel(model);後面!!!
否則無效果!!!

參考:QT - QTableView表格視圖的列寬設置

設置列寬
ui->aTabView->setColumnWidth(3, 140);
設置行高
    ui->aTabView->setRowHeight(0,35);

隱藏某一列

前提:
必須放在ui->aTabView->setModel(model);後面!!!
否則無效果!!!

函數原型:void setSectionHidden(int logicalIndex, bool hide);
頭文件:qheaderview.h
說明:參數一表示列的 下標,參數二表示是否隱藏,true爲是,false爲否。

ui->aTabView->horizontalHeader()->setSectionHidden(1,true);

單元格設置複選框

參考:

  1. Qt 之 QTableView 添加複選框(QAbstractTableModel)
  2. qt QTableView中嵌入複選框CheckBox 的四種方法總結

不像QTableWidget,有QTableWidgetItem的 setCheckState函數;
但方法總比困難多,可以通過 QStandardItem的setCheckState函數 或QTableModel類 或 委託 間接實現。
【我沒有這方面需求,所以並沒有實踐,但在此編輯,方便後續操作(回看)】

  • 利用委託重載createEditor(),激活QCheckBox。
  • 自定義模型QAbstractTableModel,通過flags()函數來實現。
  • 自定義委託QAbstractItemDelegate,通過paint()函數來實現。
  • 使用QTableView的setIndexWidget(const QModelIndex &index, QWidget *widget)來實現。
  • 我看到 QStandardItem 有 setCheckState函數。

函數原型:inline void QStandardItem::setCheckState(Qt::CheckState acheckState)
{ setData(acheckState, Qt::CheckStateRole); }
頭文件:qstandarditemmodel.h
說明:參數一表示填入CheckState枚舉的屬性。

在這裏插入圖片描述

點擊單元格,能立馬獲取或寫入值

按以往經驗,要麼用委託,要麼用監視器,要麼用過濾器,但網上只提供 過濾器的。
雖然只有過濾器的,但我認爲QStandardItemModel的itemChanged事件或許更好些。
因爲我不着急這個功能,所以並沒有進行實踐,測試代碼可行度,待我歸來,便會落實:

  1. QT事件過濾獲取tableView的currentIndex
  2. 當QStandardItemModel itemChanged發出信號時,究竟發生了什麼變化

QTableWidget 與 QTableView 的區別

參考:

  1. QTableView與QTableWidget高階使用積累
  2. QTableWidget與QTableView的區別

區別一

在這裏插入圖片描述
----------------------------------------And--------------------------------------------
在這裏插入圖片描述

QTableWidget繼承了QTableView,則QTableView是QTableWidget的父類,而QTableWidget是QTableView的子類。

因爲繼承特性,QTableWidget比QTableView要多樣化,除了QTableView私有的宏,QTableWidget大都含有QTableView。

區別二

但是QSqlTableModel能與QTableView綁定,但不能於QTableWidget綁定。

區別三

QTableView可以使用自定義的數據模型來顯示內容(也就是先要通過setModel來綁定數據源),
而QTableWidget則只能使用標準的數據模型,並且其單元格數據是QTableWidgetItem的對象來實現的(也就是不需要數據源,將逐個單元格內的信息填好即可)。

在這裏插入圖片描述

區別四

使用QTableWidget就離不開QTableWidgetItem。QTableWidgetItem用來表示表格中的一個單元格,整個表格都需要用逐個單元格構建起來。

QTableWidgetItem *item = new QTableWidgetItem(strValue);
ui->aTabWidget->setItem(0,1,item);

使用QTableView也離不開QStandardItemModel與QStandardItem。

QStandardItemModel* model = new QStandardItemModel();
QStandardItem* item = new QStandardItem(strValue);
model->setItem(0,0,item);

ui->aTabView->setModel(model);

區別五

在QTableView類中有setModel成員函數,而到了QTableWidget類中,該成員函數變成了私有,不難使用該函數設置數據模型。

在這裏插入圖片描述
在這裏插入圖片描述

區別六

QTableView沒有函數實現複選框,要通過QStandardItem的setCheckState函數或QTableModel類或委託間接實現,而QTableWidgetItem類中的setCheckState(Qt::Checked);可以直接設置複選框。

QTableWidgetItem *check=new QTableWidgetItem;
check->setCheckState (Qt::Checked);//或Unchecked
ui->aTabWidget->setItem(0,2,check); //插入複選框

  1. QTableview設置某行某列不可編輯(只讀,委託) ↩︎

  2. QHeaderView Class——Qt文檔 ↩︎ ↩︎

  3. QStandardItemModel使用技巧QStandardItemModel Class——Qt文檔 ↩︎

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章