# 12.5 wxGrid
wxGrid是一個功能強大的但是又稍微有一些復雜的窗口類用來顯示表格類型的數據.你還可以使用它來作為一個包含名稱和值兩欄的屬性編輯器.或者是通過你自己的代碼使其作為一個一般意義上的表格,用來顯示一個數據庫或者是你自己應用程序產生的特定統計數據.在某種情況你,你還可以用它來代替列表控件中的報告顯示模式,尤其是你希望在某一個特定的表格位置顯示圖片的時候.
網格控件擁有給電子表格增加行標題或者列標題的能力,用戶可以通過拖拽行或者列之間的分割線來改變行列的大小,選擇某個或者某幾個特定的表格,以及通過點擊某一格對其中的值進行編輯.每一個表格都有自己單獨的屬性包括字體,顏色,對齊方式以及自己的渲染方法(用于繪制表格)和編輯器(用于編輯表格的值).你也可以制作你自己的渲染器和編輯器:參考include/wx/generic/grid.h和 src/generic/grid.cpp中的代碼.默認情況下,表格將使用簡單文本渲染器和編輯器.如果你使用的表格擁有不同于預定義屬性的屬性,你可以創建一個"屬性提供者"對象,以便在程序運行期動態返回需要的表格的屬性.
你也可以使用包含大量數據的虛表格,這種表格的數據由應用程序自己保管,不過不是通過wxGrid類.你需要使用 wxGridTableBase的派生類并且重載其中的GetValue, GetNumberRows和GetNumberCols函數.這些函數將和你的應用程序數據(也許是數據庫)打交道.然后通過SetTable函數給網格控件增加一份數據以便網格控件可以進行對應的顯示,這種更深入的技巧在你的wxWidgets發行版的samples/grid目錄中進行了演示,如下圖所示:

下面的代碼創建了一個簡單的8行10列的表格:
```
#include "wx/grid.h"
// 創建一個wxGrid對象
wxGrid* grid = new wxGrid(frame, wxID_ANY,
wxDefaultPosition, wxSize(400, 300));
// 然后調用CreateGrid設置表格的大小
grid->CreateGrid(8, 10);
// 我們可以單獨給某一行或者某一列設置象素單位的寬度或高度.
grid->SetRowSize(0, 60);
grid->SetColSize(0, 120 );
// 然后設置表格內的文本內容
grid->SetCellValue(0, 0, wxT("wxGrid is good"));
// 可以指定某些表格是只讀的
grid->SetCellValue(0, 3, wxT("This is read-only"));
grid->SetReadOnly(0, 3);
// 還可以指定某個表格的文本顏色
grid->SetCellValue(3, 3, wxT("green on grey"));
grid->SetCellTextColour(3, 3, *wxGREEN);
grid->SetCellBackgroundColour(3, 3, *wxLIGHT_GREY);
// 還可以指定某一列的數據采用數字的格式
// 這里我們設置第5列的數字格式為寬度為6,小數點后保留2位的浮點數.
grid->SetColFormatFloat(5, 6, 2);
grid->SetCellValue(0, 6, wxT("3.1415"));
// 設置網格的大小為可以顯示所有內容的最小大小.
grid->Fit();
// 設置其父窗口的客戶區大小以便放的下整個網格.
frame->SetClientSize(grid->GetSize());
```
wxGrid系統中的類
正如你已經理解到的那樣,wxGrid類是許多的類交互作用的結果.下表展示了wxGrid系統中的類以及它們之間的相互關系:
| wxGrid | 最主要的網格類,用來存放別的用于管理表格,行和列等的其它的窗口類. |
|:--- |:--- |
| wxGridTableBase | 這個類允許應用程序想虛擬的網格提供數據.SetTable函數將其派生類的一個實例掛載入網格類. |
| wxGridCellAttr | 保存用于渲染表格的屬性數據.你可以顯式的通過類似SetCellTextColour這樣的函數更改表格的屬性.你也可以通過SetAttr函數設置某個單獨的表格的屬性或者是通過SetRowAttr和SetColAttr函數設置某一列或者某一行的屬性. 你也可以在你自定義的表格類中通過GetAttr函數返回指定表格的屬性. |
| wxGridCellRenderer | 這個類負責對表格進行渲染和繪制.你可以通過改變wxGridCellAttr(或者通過wxGrid::SetCellRenderer函數)中對應的類的實例來改變某個表格的數據格式,你也可以直接通過wxGrid::SetDefaultRenderer函數更改整個表格的顯示方式.這是一個虛類, 你通常需要使用一個預定義的派生類或者自己實現一個派生類.預定義的派生類包括wxGridCellStringRenderer, wxGridCellNumberRenderer,wxGridCellFloatRenderer和wxGridCellBoolRenderer 等. |
| wxGridCellEditor | 這個類負責實現對表格數據的即時編輯功能.這個虛類的派生類的實例可以和某個表格,某行,某列甚至整個表格綁定. 比如說,使用wxGrid::SetCellEditor函數來給某個表格中的一格設置編輯器. 預定義的派生類包括 wxGridCellTextEditor, wxGridCellFloatEditor, wxGridCellBoolEditor, wxGridCellNumberEditor和wxGridCellChoiceEditor. |
| wxGridEvent | 這個類包含了各種網格相關事件的信息,比如鼠標在表格上單擊事件,表格數據改變事件,表格被選中事件,表格編輯器被顯示或者隱藏事件等. |
| wxGridRangeSelectEvent | 當用戶選擇一組表格以后將產生這個事件. |
| wxGridSizeEvent | 當某一行或者某一列的大小發生變化的時候產生這個事件. |
| wxGridEditorCreatedEvent | 當創建某個編輯器的時候產生這個事件. |
| wxGridCellCoords | 這個類用來代表表格中的某一格. 使用GetRow和GetCol函數獲取具體的位置. |
| wxGridCellCoordsArray | 這是一個wxGridCellCoords類型的數組,用在函數GetSelectedCell, GetSelectionBlockTopLeft和GetSelectionBlockBottomRight的返回值中. |
wxGrid的事件
下面列出了wxGrid的主要的事件映射宏.注意對于其中任何一個EVT_GRID_...宏,都對應的還有一個EVT_GRID_CMD_...宏,后者比前者多一個標識符參數,可以用來避免僅僅出于這個原因而重新定義新的類.
| EVT_GRID_CELL_LEFT_CLICK(func) | 用戶用左鍵單擊某個表格. |
|:--- |:--- |
| EVT_GRID_CELL_RIGHT_CLICK(func) | 用戶用郵件單擊某個表格. |
| EVT_GRID_CELL_LEFT_DCLICK(func) | 用戶用左鍵雙擊某個表格. |
| EVT_GRID_CELL_RIGHT_DCLICK(func) | 用戶用右鍵雙擊某個表格. |
| EVT_GRID_LABEL_LEFT_CLICK(func) | 用戶用左鍵單擊某個標題. |
| EVT_GRID_LABEL_RIGHT_CLICK(func) | 用戶用右鍵單擊某個標題. |
| EVT_GRID_LABEL_LEFT_DCLICK(func) | 用戶用左鍵雙擊某個標題. |
| EVT_GRID_LABEL_RIGHT_DCLICK(func) | 用戶用右鍵雙擊某個標題. |
| EVT_GRID_CELL_CHANGE(func) | 用戶更改了某個表格的數據. |
| EVT_GRID_SELECT_CELL(func) | 用戶選中了某個表格. |
| EVT_GRID_EDITOR_HIDDEN(func) | 某個表格的編輯器已隱藏. |
| EVT_GRID_EDITOR_SHOWN(func) | 某個表格的編輯器已顯示. |
| EVT_GRID_COL_SIZE(func) | 用戶通過拖拽改變了某列大小. |
| EVT_GRID_ROW_SIZE(func) | 用戶通過拖拽改變某行大小. |
| EVT_GRID_RANGE_SELECT(func) | 用戶選取了一組連續的單元格. |
| EVT_GRID_EDITOR_CREATED(func) | 某個單元格的編輯器已被創建. |
wxGrid的成員函數
下面按功能列出了比較重要的wxGrid的成員函數.完整的成員函數列表以及其它相關類的成員函數請參考相關手冊.
用于創建,刪除和數據交互的函數
AppendCols和AppendRows用來在最下邊或者最右邊增加行或者列,或者你還可以使用InsertCols和InsertRows在某個特定位置插入行或者列. 如果你使用了自定義的表格,你需要重載同名的這些函數.
GetNumberCols和GetNumberRows函數用來獲取和網格綁定的表格數據的列數和行數.
CreateGrid這個函數用來以指定的行數和列數初始化網格的數據.你應該在創建網格實例以后馬上調用這個函數.這個函數會為網格創建一個用于操作簡單文本數據的表格,表格的所有相關數據都將保存在內存中.如果你的應用程序要處理更負責的數據類型或者更復雜的依賴關系,或者說要處理很大量的數據,你可以實現自己的表格派生類,然后使用wxGrid::SetTable函數將其和某個網格對象綁定.
ClearGrid函數清除所有的網格綁定表格中的數據并且刷新網格的顯示.表格本身并不會被釋放.如果你使用了自定義的表格類,記得重載其wxGridTableBase::Clear成員函數以實現對應功能. ClearSelection函數用來去選擇所有當前選擇的單元格.
DeleteCols和DeleteRows函數分別用來刪除列和行.
GetColLabelValue函數返回某個指定列的標簽.默認的表格類提供的列標簽是從A, B?Z, AA, AB?ZZ, AAA?等,如果你使用自定義的表格類,你可以重定義wxGridTableBase::GetColLabelValue函數以返回相應的標簽. 類似的, GetrowLabelValue函數用來返回指定行的標簽. 默認的行標簽為數字.如果你使用自定義的表格,可以重載其wxGridTableBase::GetRowLabelValue函數來提供自定義的默認行標簽.你還可以使用SetColLabelValue和SetRowLabelValue函數來指定某個特定行列的標簽.
GetCellValue用來返回特定單元格內的文本.對于那些使用簡單網格類的應用程序,你可以使用這個函數和對應的SetCellValue函數來操作單元格內的文本數據.對于更復雜的使用了自定義表格的程序,這個函數只能用于返回那些包含文本內容的單元格的內容.
界面相關函數
一下這些函數將會影響到網格控件的界面更新
BeginBatch和EndBatch函數阻止它們之間的對網格對象的操作引起的界面更新. 界面更新將在GetBatchCount返回0的情況下更新(譯者注:BeginBatch增加這個值而EndBatch減少這個值).
EnableGridLines設置允許或者禁止繪制網格線. GridLinesEnabled則返回當前設置.
ForceRefresh用來強制立即更新網格顯示. 你應該使用這個函數來代替wxWindow::Refresh函數.
Fit函數用來使得網格控件將自己的大小更改為當前行數和列數所要求的最小大小.
GetCellAlignment返回指定單元格在垂直和水平方向上的對齊方式. GetColLabel返回列標簽的對齊方式, GetRowLabelAlignment返回行標簽的對齊方式. GetDefaultCellAlignment返回默認單元格的對齊方式. 這些函數都有對應的Set開始的設置函數. 水平對齊的值可以為wxALIGN_LEFT, wxALIGN_CENTRE (wxALIGN_CENTER)或wxALIGN_RIGHT. 垂直對齊的枚舉值可以為wxALIGN_TOP, wxALIGN_CENTRE (wxALIGN_CENTER)或wxALIGN_BOTTOM之一.
GetCellBackgroundColour返回指定單元格背景顏色. GetdefaultCellBackgroundColour返回默認單元格背景顏色.GetLabelBackgroundColour返回標簽背景顏色.這些函數也都有對應的設置函數.
GetCellFont函數返回指定單元格字體, GetdefaultCellFont返回默認單元格字體. GetLabelFont則返回標簽文本字體.這些函數也都有對應的設置函數.
GetCellTextColour返回指定單元格的文本顏色. GetdefaultCellTextColour返回默認單元格的文本顏色,GetLabelTextColour則返回標簽文本顏色.這些函數同樣擁有對應的設置函數
SetGridLineColour和GetGridLineColour函數用來更改和獲取網格線的顏色.
SetColAttr和SetRowAttr用來設置某一行或者某一列中所有單元格的屬性.
SetColFormatBool, SetColFormatNumber, SetColFormatFloat和SetColFormatCustom函數可以用來更改某一列的單元格內容格式.
和wxGrid大小相關的函數
下面的這些函數的參數都以象素作為單位.
AutoSize函數自動將所有單元格的大小按照其內容進行調整.對應的還有AutoSizeColumn, AutoSizeColumns, AutoSizeRow和AutoSizeRows函數.
CellToRect返回指定單元格的大小和位置,以wxRect表示.
SetColMinimalWidth和SetRowMinimalHeight用來設置最小行高和最小列寬, 對應的獲取函數為GetColMinimalWidth和GetrowMinimalHeight.
下面這些函數用來獲取各種尺寸大小: GetColLabelSize, GeTDefaultColLabelSize, GeTDefaultColSize, GetColSize, GetdefaultRowLabelSize, GeTRowSize, GeTDefaultRowSize和GeTRowLabelSize. 它們都有對應的設置函數.
如果你想在表格周圍設置額外的邊距,可以使用SetMargins函數.
XToCol和YToRow函數用來將X和Y座標轉換成對應的行數或列數.要找到距離其右邊線最近的對應于X座標值的列號,使用XToEdgeOfCol函數. 要找到具體其底邊線最近的對應于Y座標的行號,使用YToEdgeOfRow函數.
選擇和游標函數
下面的這些函數用于控制網格的游標和選擇操作
GetGridCursorCol和GetGridCursorRow函數返回當前游標所處的行號和列號.相應的設置函數為SetGridCursor.
你可以用下面的函數以每次一格的方式移動游標:MoveCursorDown, MoveCursorLeft, MoveCursorRight和MoveCursorUp.如果希望在移動的時候跳到第一個非空單元格,則對應的使用 MoveCursorDownBlock, MoveCursorLeftBlock, MoveCursorRightBlock和MoveCursorUpBlock函數.
如果想一次移動一頁,可以使用MovePageDown和MovePageUp函數,頁大小由網格窗口的大小決定.
GetSelectionMode返回當前設置的選擇模式,它的值為下列之一: wxGrid::wxGridSelectCells (默認模式,以單元格為單位選擇), wxGrid::wxGridSelectRows (以行為單位選擇), and wxGrid::wxGridSelectColumns (以列為單位進行選擇). 對應的設置函數為SetSelectionMode.
GetSelectedCells用來獲取當前選中的單元格列表,它的返回值是wxGridCellCoordsArray類型,其中包含所有被選中的單元格.GetSelectedCols和GetSelectedRows則返回當前選中的所有行和列.因為用戶可以選擇多個不連續的單元格塊,所以GetSelectionBlockTopLeft和GetSelectionBlockBottomRight返回的也是一個 wxGridCellCoordsArray類型的類表. 你需要自己群舉這些列表以遍歷所有選中的單元格.
IsInSelection用于查詢指定的單元格是否被選中,參數為行號列號或者wxGridCellCoords類型. IsSelection則返回整個網格是否有任何一格單元格被選中.
使用SelectAll選擇整個表格, SelectCol函數用于選擇某列, SelectRow函數用于選擇某行. SelectBlock用于選擇連續的一塊區域,參數為四個代表左上角及右下角的座標的整數,或者兩個wxGridCellCoords類型的參數.
其它wxGrid函數
GetTable函數返回網格用于保存內部數據的綁定表格對象.如果你使用了CreateGrid函數,則已經創建了一個用戶保存簡單文本數據的表格,或者,你已經使用SetTable函數設置了一個你自定義的表格類型.
GetCellEditor和SetCellEditor用來獲取或者設置指定單元格綁定的編輯器指針. GetdefaultEditor和SetDefaultEditor用來獲取和設置所有單元格使用的默認編輯器.
GetCellRenderer和SetCellRenderer獲取或者設置指定單元格綁定的渲染器的指針. GeTDefaultRenderer和SetDefaultRenderer用來獲取和設置所有單元格使用的渲染器.
ShowCellEditControl和HideCellEditControl用來在相應的位置顯示和隱藏當前單元格指定的編輯控件.這兩個函數通常是在用戶點擊某個單元格來編輯單元格的值或者按下回車鍵和取消鍵(或者單擊另外一個窗口)以關閉編輯器的時候自動調用的. SaveEditControlValue函數用來將編輯器中的值傳輸到單元格中,這個函數在關閉網格或者從網格獲取數據的時候你可以考慮調用以便網格的值反應最新編輯的值.
EnableCellEditControl函數允許或者禁止對網格數據進行編輯. 這個函數調用的時候,網格類將會產生wxEVT_GRID_EDITOR_SHOWN或wxEVT_GRID_EDITOR_HIDDEN事件. IsCellEditControlEnabled函數用來檢測是否當前單元格可以被編輯. IsCurrentCellReadOnly則返回是否當前單元格是只讀的.
EnableDragColSize允許或者禁止通過拖拽更改列寬. EnableDragGridSize允許或者禁止通過拖拽改變單元格大小. EnableDragRowSize允許或者禁止通過拖拽改變行高.
EnableEditing的參數如果為false,則設置整個網格為只讀狀態. 如果為true,則網格恢復到默認狀態.在默認狀態,單元格和行以及列都可以有自己的是否可編輯標記,這個標記可以通過 wxGridCellAttribute::SetReadOnly改變,針對單元格的只讀設置可以直接通過wxGridCellAttribute:: SetReadOnly函數改變.IsEditable函數返回是否整個網格是可編輯的.
你也可以通過調用SetReadOnly函數改變某個單元格的只讀狀態,IsReadOnly則用來獲取這個設置.
IsVisible函數在單元格部分或者全部可見的時候返回true,MakeCellVisible則確保某個單元格出于可見區域.
- 第一章 介紹
- 1.1 為什么要使用wxWidgets?
- 1.2 wxWidgets的歷史
- 1.3 wxWidgets社區
- 1.4 wxWidgets和面向對象編程
- 1.5 wxWidgets的體系結構
- 1.6 許可協議
- 第一章小結
- 第二章 開始使用
- 2.1 一個小例子
- 2.2 應用程序類
- 2.3 Frame窗口類
- 2.4 事件處理函數
- 2.5 Frame窗口的構造函數
- 2.6 完整的例子
- 2.7 wxWidgets程序一般執行過程
- 2.8 編譯和運行程序
- 第二章小結
- 第三章 事件處理
- 3.1 事件驅動編程
- 3.2 事件表和事件處理過程
- 3.3 過濾某個事件
- 3.4 掛載事件表
- 3.5 動態事件處理方法
- 3.6 窗口標識符
- 3.7 自定義事件
- 第三章小結
- 第四章 窗口的基礎知識
- 4.1 窗口解析
- 4.2 窗口類概覽
- 4.3 基礎窗口類
- 4.4 頂層窗口
- 4.5 容器窗口
- 4.6 非靜態控件
- 4.7 靜態控件
- 4.8 菜單
- 4.9 控制條
- 第四章小結
- 第五章繪畫和打印
- 5.1 理解設備上下文
- 5.2 繪畫工具
- 5.3 設備上下文中的繪畫函數
- 5.4 使用打印框架
- 5.5 使用wxGLCanvas繪制三維圖形
- 第五章小節
- 第六章處理用戶輸入
- 6.1 鼠標輸入
- 6.2 處理鍵盤事件
- 6.3 處理游戲手柄事件
- 第六章小結
- 第七章使用布局控件進行窗口布局
- 7.1 窗口布局基礎
- 7.2 窗口布局控件
- 7.3 使用布局控件進行編程
- 7.4 更多關于布局的話題
- 第七章小結
- 第八章使用標準對話框
- 8.1信息對話框
- 8.2 文件和目錄對話框
- 8.3 選擇和選項對話框
- 8.4 輸入對話框
- 8.5 打印對話框
- 第八章小結
- 第九章創建定制的對話框
- 9.1 創建定制對話框的步驟
- 9.2 一個例子:PersonalRecordDialog
- 9.3 在小型設備上調整你的對話框
- 9.4 一些更深入的話題
- 9.5 使用wxWidgets資源文件
- 第九章小結
- 第十章使用圖像編程
- 10.1 wxWidgets中圖片相關的類
- 10.2 使用wxBitmap編程
- 10.3 使用wxIcon編程
- 10.4 使用wxCursor編程
- 10.5 使用wxImage編程
- 10.6 圖片列表和圖標集
- 10.7 自定義wxWidgets提供的小圖片
- 第十章小結
- 第十一章剪貼板和拖放操作
- 11.1 數據對象
- 11.2 使用剪貼板
- 11.3 實現拖放操作
- 第十一章小結
- 第十二章高級窗口控件
- 12.1 wxTreeCtrl
- 12.2 wxListCtrl
- 12.3 wxWizard
- 12.4 wxHtmlWindow
- 12.5 wxGrid
- 12.6 wxTaskBarIcon
- 12.7 編寫自定義的控件
- 第十二章小結
- 第十三章數據結構類
- 13.1 為什么沒有使用STL?
- 13.2 字符串類型
- 13.3 wxArray
- 13.4 wxList和wxNode
- 13.5 wxHashMap
- 13.6 存儲和使用日期和時間
- 13.7 其它常用的數據類型
- 第十三章小結
- 第十四章文件和流操作
- 14.1 文件類和函數
- 14.2 流操作相關類
- 第十四章小結
- 第十五章內存管理,調試和錯誤處理
- 15.1 內存管理基礎
- 15.2 檢測內存泄漏和其它錯誤
- 15.3 構建自防御的程序
- 15.4 錯誤報告
- 15.5 提供運行期類型信息
- 15.6 使用wxModule
- 15.7 加載動態鏈接庫
- 15.8 異常處理
- 15.9 調試提示
- 第十五章小結
- 第十六章編寫國際化程序
- 16.1 國際化介紹
- 16.2 從翻譯說起
- 16.3 字符編碼和Unicode
- 16.4 數字和日期
- 16.5 其它媒介
- 16.6 一個小例子
- 第十六章小結
- 第十七章編寫多線程程序
- 17.1 什么時候使用多線程,什么時候不要使用
- 17.2 使用wxThread
- 17.3 用于線程同步的對象
- 17.4 多線程的替代方案
- 第十七章小結
- 第十八章使用wxSocket編程
- 18.1 Socket類和功能概覽
- 18.2 Socket及其基本處理介紹
- 18.3 Socket標記
- 18.4 使用Socket流
- 18.5 替代wxSocket
- 第十八章小結
- 第十九章使用文檔/視圖框架
- 19.1 文檔/視圖基礎
- 19.2 文檔/視圖框架的其它能力
- 19.3 實現Undo/Redo的策略
- 第十九章小結
- 第二十章完善你的應用程序
- 20.1 單個實例和多個實例
- 20.2 更改事件處理機制
- 20.3 降低閃爍
- 20.4 實現聯機幫助
- 20.5 解析命令行參數
- 20.6 存儲應用程序資源
- 20.7 調用別的應用程序
- 20.8 管理應用程序設置
- 20.9 應用程序安裝
- 20.10 遵循用戶界面設計規范
- 20.11 全書小結