1. 程式人生 > 其它 >wxpython中的網格控制元件

wxpython中的網格控制元件

建立網格

網格控制元件是用以顯示一個二維的資料集的。要使用該控制元件顯示有用的資訊,你需要告訴該控制元件它工作所基於的是什麼資料。在wxPython中,有兩種不同的機制用於在網格控制元件中處理資料,它們之間在處理資料的新增,刪除和編輯的方式上有些許的不同。

  • 網格控制元件可以直接處理每行和每列中的值。
  • 資料可以通過使用一個網格表(grid table)來間接地處理。

較簡單的一種是使用網格控制元件直接處理值。在這種情況下,網格維護著資料的一份拷貝。在這種情況下,如果有大量的資料或你的應用程式已經有了一個現存的網格類的資料結構,那麼這可能顯得比較笨拙。如果是這樣,你可以使用一個網格表來處理該網格的資料。

建立簡單的網格

wx.gridGrid(parent, id=ID_ANY, pos=DefaultPosition, size=DefaultSize,
     style=WANTS_CHARS, name=GridNameStr)
wx.WANTS_CHARS樣式是網格的預設樣式,除此之外,wx.grid.Grid沒有為自己定義特別的樣式。由於網格類的複雜性,所以在程式中,你一般要自定義網格類的一個子類來實現一個網格,而非直接使用wx.grid.Grid的一個例項。 和我們所見過的別的控制元件不同,呼叫該建構函式不足以建立一個可用的網格。有兩個方法用以初始化網格
  • CreateGrid()
  • SetTable()
CreateGrid(numRows, numCols, selmode=wx.grid.Grid.SelectCells)
引數selmode指定了網格中單元格的選擇模式,預設值是wx.grid.Grid.SelectCells,意思是一次只選擇一個單元格。其它的值有wx.grid.Grid.SelectRows,意思是一次選擇整個行,wx.grid.Grid.SelectionColumns,意思是一次選擇整個列。 在內部,使用CreateGrid()初始化網格之後,wxPython設定了一個二維的字串陣列。一旦網格被初始化了,你就可以使用方法SetCellValue(row, col, s)來放置資料。如果你想獲取特定座標處的值,你可以使用函式GetCellValue(row, col),該函式返回字串。要一次清空整個網格,你可以使用方法ClearGrid()。

使用網格表建立網格

對於較複雜的情況,你可以將你的資料儲存在一個網格表中,網格表是一個單獨的類,它儲存資料並與網格控制元件互動以顯示資料。推薦在下列情況下使用網格表:
  • 網格的資料比較複雜
  • 資料儲存在你的系統中的另外的物件中
  • 網格太大以致於不能一次整個被儲存到記憶體中
要使用一個網格表,你需要要建立wx.grid.PyGridTableBase的子類。該子類必須覆蓋父類wx.grid.GridTableBase的一些方法。下面展示一個例項:
import wx
import wx.grid


class TestTable(wx.grid.GridTableBase):
    def __init__(self):
        wx.grid.GridTableBase.__init__(self)
        self.data = {(1, 1): "Here",
                     (2, 2): "is",
                     (3, 3): "some",
                     (4, 4): "data",
                     }

        self.odd = wx.grid.GridCellAttr()
        self.odd.SetBackgroundColour("sky blue")
        self.odd.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD))

        self.even = wx.grid.GridCellAttr()
        self.even.SetBackgroundColour("sea green")
        self.even.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD))

    # these five are the required methods
    def GetNumberRows(self):
        return 50

    def GetNumberCols(self):
        return 50

    def IsEmptyCell(self, row, col):
        return self.data.get((row, col)) is not None

    def GetValue(self, row, col):
        value = self.data.get((row, col))
        if value is not None:
            return value
        else:
            return ''

    def SetValue(self, row, col, value):
        self.data[(row, col)] = value

    # the table can also provide the attribute for each cell
    def GetAttr(self, row, col, kind):
        attr = [self.even, self.odd][row % 2]
        attr.IncRef()
        return attr


class TestFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, title="Grid Table",
                          size=(640, 480))

        grid = wx.grid.Grid(self)

        table = TestTable()
        grid.SetTable(table, True)


app = wx.App()
frame = TestFrame()
frame.Show()
app.MainLoop()
要使網格表有效,你必須覆蓋5個方法。當然也可以覆蓋更多。
  • GetNumberCols():返回顯示在網格中的列的數目
  • GetNumberRows():返回顯示在網格中的行的數目
  • GetValue(row, col):返回座標(row, col)處的值
  • IsEmptyCell(row, col):如果座標(row, col)處的單元格為空的話,返回True。否則返回False。
  • SetValue(row, col, value):如果你需要的話,它使你能夠更新你底層的資料結構以匹配使用者的編輯。對於一個只讀的表,你仍然需要宣告該方法,但是你可以通過pass來使它什麼也不做。該方法在當用戶編輯一個單元格時自動被呼叫。
要將網格表例項附著於你的表的例項,要呼叫SetTable(table,takeOwnership=False,selmode=wx.grid.Grid.SelectCells)方法。其中引數table是你的wx.grid.PyGridTableBase的例項。引數takeOwnership使得網格控制元件擁有這個表。如果takeOwnership為True,那麼當網格被刪除時,該表也被wxPython系統刪除。引數selmode作用等同於在CreateGrid()中的作用。 你能夠覆蓋的另一個方法是Clear(),它在當對網格呼叫ClearGrid()時被呼叫,如果適當的話,你可以覆蓋該方法來清除潛在的資料來源。