1. 程式人生 > >QT QTableView QTableWidget 複雜表頭(多行表頭) 、(凍結、固定特定的行)

QT QTableView QTableWidget 複雜表頭(多行表頭) 、(凍結、固定特定的行)

對於所有前端開發人員會留意到,我們在開發過程中對於表格使用頻率還是挺高的,使用QT框架開發時候我們使用QTableView或者QTableWidget建立表格。

其中表格分為 表格頭與表格體:

對於簡單地表格,我們可以設定表頭來滿足我們的要求(當然也可以隱藏表頭),不過對於定製化的表頭,我們能做的不是特別多。特別是對於複雜的表頭,使用自帶的表頭,無論怎麼設定都不太可能達到需求。例如我最近接到的一個專案,需求是:

我們分析一下這個表格有什麼特點:

1.表頭不是簡單的一行,而是兩行。

2.表頭有單元格的合併。

3.部分表頭中間有使用漸變的分隔線且分割線不是上下充滿表格的。

如果能解決上面三個問題,我們基本都可以把這個表格做出來了。這個表頭明顯是一個比較複雜的表頭。對於只對QT提供的API或者CSS上面三個問題,沒有一個能夠解決的。

這時候可能會有老師提出解決辦法:給header 設定itemDelegate,自己在itemDelegate中重寫paintEvent,自己畫表頭。 因為我們都知道,自己畫單元格,要更靈活,滿足更多需求。但是我們平時都是對單元格進行重繪,並不是對header的單元格進行重繪。於是就去搜索QT的幫助文件,驚喜的發現居然有設定itemdelegate的API,心裡覺得有戲於是建立 ItemDelegate類,對header進行設定如下

tableWidget->horizontalHorizon()->setItemDelegate(new ItemDelegate());

可是結果卻是令人失望的,沒有一點效果。於是反身去查詢QT 關於這部分的介紹,終於找到了原因:

結果就顯而易見了,對於headerView,並不能使用ItemDelegate進行重繪。

那麼我們就要另外想辦法了,經過分析,剛開始提出了兩種方案:

解決方案
描述 優點 缺點
方案一
  • 隱藏表頭
  • 前兩行當做表頭
  • 內容行從第三行開始
  • 對錶格設定itemDelegate,對前兩行的表頭進行重繪
  • 一個QTableWidget,實現起來方便一些。
  • 當出現滾動條,表頭會隨著著內容表格個移動,不符合大眾習慣。
  • 改變了內容表格的整個原有序列,所有的行數都需要比原來大2,對所有的API進行重寫工作難不高,複雜度比較高。
方案二
  • 使用一個QTableWidget命名為m_frozonTableWgt作為表頭。
  • 使用另外一個QTableWidget作為內容顯示的表格。
  • m_frozonTableWgt隱藏表頭、隱藏滾動條、只顯示2行的內容表格、顯示到內容表格上方、只佔據內容表的表頭高度、設定ItemDelegate進行重繪。
  • 內容表格,顯示錶頭,高度設定成m_frozonTableWgt前兩行的高度。
  • 最終效果更好,體驗更好。
  • 需要對2個QTableWidget進行操作,比較麻煩。
  • 需要對錶頭的QTableWidget進行鎖死(固定)。
  • 3.需要對2個QtableWidget進行聯動設定

總結一下就是:

  • 第一種方案比較簡單,但是最終體驗效果不太好。
  • 第二種方案實現起來比較複雜,但是最終體驗效果比較好。

本著成就客戶與自我成長的態度,最終選擇了第二種解決方案。

我們首先要做的就是建立一個繼承於QTableWidget的一個類

class TDMSummaryTableWgt : public QTableWidget