wxPython中wx.gird.Gird添加按鈕的實(shí)現(xiàn)
前言
wx.gird.Gird是實(shí)現(xiàn)類似excel表格的庫(kù),擴(kuò)展面很廣,本文講述它添加按鈕,按鈕響應(yīng)的內(nèi)容
實(shí)現(xiàn)效果圖如下:

本文基于wxPython 4.2.0版本上開發(fā)。需要特別注意,wxPython版本之間基礎(chǔ)庫(kù)的差異巨大。
wx.gird.Gird表格中添加按鈕,共分為三部
第一步、使用GridCellRenderer與GridCellEditor派生出表格安置button控件的渲染器與編輯
第二步、wx.gird.Gird表格創(chuàng)建,添加按鈕與事件響應(yīng)
第三步、調(diào)試代碼與測(cè)試功能
1、派生按鈕渲染器與按鈕編輯器
首先我們需要先實(shí)現(xiàn)在兩個(gè)類,一個(gè)是單元格渲染器(wx.grid.GridCellRenderer)派生渲染按鈕,一個(gè)單元格編輯器(wx.grid.GridCellEditor)派生編輯按鈕
代碼如下:
import wx.grid
class ButtonRenderer(wx.grid.GridCellRenderer):
def __init__(self, button):
wx.grid.GridCellRenderer.__init__(self) # 初始化GridCellRenderer基類
self.button = button
def Draw(self, grid, attr, dc, rect, row, col, isSelected):
self.button.SetSize(rect) # 設(shè)置按鈕大小為單元格大小
state = wx.CONTROL_SELECTED if isSelected else wx.CONTROL_CURRENT # 設(shè)置按鈕狀態(tài)
bmp = wx.Bitmap(rect.width, rect.height) # 創(chuàng)建一個(gè)和單元格大小相同的位圖
dc2 = wx.MemoryDC(bmp) # 創(chuàng)建一個(gè)內(nèi)存設(shè)備上下文,用于在位圖上繪制
wx.RendererNative.Get().DrawPushButton(self.button, dc2, (0, 0, rect.width, rect.height), state) # 在位圖上繪制按鈕
dc.Blit(rect.x, rect.y, rect.width, rect.height, dc2, 0, 0, wx.COPY, True) # 將位圖復(fù)制到單元格上,覆蓋原有的內(nèi)容
# 在單元格中繪制標(biāo)簽
label = grid.GetTable().GetValue(row, col) # 獲取單元格的值
dc.DrawLabel(label, rect, wx.ALIGN_CENTER) # 在單元格中居中繪制標(biāo)簽
class ButtonEditor(wx.grid.GridCellEditor):
def __init__(self, button):
wx.grid.GridCellEditor.__init__(self) # 初始化GridCellEditor基類
self.button = button
self.SetControl(button)
def Create(self, parent, id, evtHandler):
pass
def BeginEdit(self, row, col, grid):
pass
def EndEdit(self, row, col, grid, oldVal):
pass- 這段代碼是用于創(chuàng)建一個(gè)在表格單元格中顯示按鈕的自定義表格單元格渲染器(ButtonRenderer)和單元格編輯器(ButtonEditor)。
- ButtonRenderer的功能是在表格單元格中繪制按鈕。它接收一個(gè)wx.Button實(shí)例,然后在表格單元格內(nèi)繪制按鈕和標(biāo)簽。它重載了Draw方法,該方法接收單元格的位置、大小、單元格的行列信息等參數(shù),通過(guò)調(diào)用wx.RendererNative.Get().DrawPushButton方法來(lái)繪制按鈕,然后在單元格中繪制標(biāo)簽。
- ButtonEditor是用于允許用戶編輯表格單元格中的按鈕的單元格編輯器。它接收一個(gè)wx.Button實(shí)例,并在單元格中顯示該按鈕。它重載了Create、BeginEdit、EndEdit,其中Create方法負(fù)責(zé)創(chuàng)建一個(gè)窗口控件來(lái)表示單元格中的編輯器,BeginEdit方法在用戶開始編輯單元格時(shí)被調(diào)用,EndEdit方法在用戶完成編輯時(shí)被調(diào)用
2、表格實(shí)現(xiàn)
按照前言的樣式,我們需要實(shí)現(xiàn)一個(gè)3x3的表格
內(nèi)容是 Name, Age,按鈕
使用wx.gird.Gird來(lái)實(shí)現(xiàn),按鈕部分會(huì)使用上面派生的兩個(gè)類
具體代碼如下:
import wx
import wx.grid
# 定義一個(gè)包含姓名和年齡的列表,后面作為列表的數(shù)據(jù)
pn = [['張三', '18'],
['李四', '21'],
['王五', '39']]
# 定義一個(gè)繼承自 wx.grid.Grid 的類 MyGrid
class MyGrid(wx.grid.Grid):
def __init__(self, parent):
# 調(diào)用 wx.grid.Grid 的初始化函數(shù)
wx.grid.Grid.__init__(self, parent, -1)
# 創(chuàng)建一個(gè) 3 行 3 列的網(wǎng)格
self.CreateGrid(3, 3)
# 設(shè)置第一列的標(biāo)題為 "Name"
self.SetColLabelValue(0, "Name")
# 設(shè)置第二列的標(biāo)題為 "Age"
self.SetColLabelValue(1, "Age")
# 設(shè)置第三列為空,即沒(méi)有標(biāo)題
self.SetColLabelValue(2, "")
# 在第3列的每一行中添加一個(gè)按鈕
for i in range(self.GetNumberRows()):
#將第一列 Name 與 第二列 Age 填充 姓名與年齡
self.SetCellValue(i, 0, pn[i][0])
self.SetCellValue(i, 1, pn[i][1])
btn = wx.Button(self, id=i, label="Delete") # 創(chuàng)建一個(gè)名為 "Delete" 的按鈕,并綁定到 id=i 上
#這兩行用上了前面派生的類
self.SetCellRenderer(i, 2, ButtonRenderer(btn)) # 在第 i 行的第 2 列中設(shè)置單元格渲染器為 ButtonRenderer(btn)
self.SetCellEditor(i, 2, ButtonEditor(btn)) # 在第 i 行的第 2 列中設(shè)置單元格編輯器為 ButtonEditor(btn)
self.SetCellValue(i, 2, "Delete") # 在第 i 行的第 2 列中設(shè)置單元格值為 "Delete" ,這一句沒(méi)有,會(huì)有顯示缺陷,可自
btn.Bind(wx.EVT_BUTTON, self.OnDeleteButtonClick) # 給按鈕綁定一個(gè)事件處理函數(shù) OndeletePlan
# 定義一個(gè)按鈕點(diǎn)擊事件處理函數(shù)
def OnDeleteButtonClick(self, event):
# 獲取按鈕所在的單元格的行號(hào),其實(shí)是按鈕的ID編號(hào)
row = event.GetId()
# 獲取單元格編輯器中的按鈕
aa: wx.Button = self.GetCellEditor(row, 2).button
# 解除按鈕的事件綁定,這個(gè)事件不解除,無(wú)法刪除這一行數(shù)據(jù)
aa.Unbind(wx.EVT_BUTTON)
# 刪除該行
self.DeleteRows(row)
3、編輯調(diào)試代碼:
調(diào)試代碼如下:
class MyFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="My Grid")
# 創(chuàng)建一個(gè)MyGrid對(duì)象, 上面實(shí)現(xiàn)的
self.grid = MyGrid(self)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.grid, 1, wx.EXPAND | wx.ALL, 5)
self.SetSizer(sizer)
self.Fit()
# 運(yùn)行標(biāo)配
if __name__ == "__main__":
frame = MyFrame()
frame.Show()
app.MainLoop()

4、完整可運(yùn)行代碼
下面貼出完整的代碼
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2023/3/16 22:44
# @Author : 魂尾
# @File : 05在gird中添加刪除按鈕.py
# @Description : 一個(gè)3x3的表格,可以通過(guò)Delete按鈕刪除對(duì)應(yīng)行
import wx
import wx.grid
# 定義一個(gè)包含姓名和年齡的列表,后面作為列表的數(shù)據(jù)
pn = [['張三', '18'],
['李四', '21'],
['王五', '39']]
class ButtonRenderer(wx.grid.GridCellRenderer):
def __init__(self, button):
wx.grid.GridCellRenderer.__init__(self) # 初始化GridCellRenderer基類
self.button = button
def Draw(self, grid, attr, dc, rect, row, col, isSelected):
self.button.SetSize(rect) # 設(shè)置按鈕大小為單元格大小
state = wx.CONTROL_SELECTED if isSelected else wx.CONTROL_CURRENT # 設(shè)置按鈕狀態(tài)
bmp = wx.Bitmap(rect.width, rect.height) # 創(chuàng)建一個(gè)和單元格大小相同的位圖
dc2 = wx.MemoryDC(bmp) # 創(chuàng)建一個(gè)內(nèi)存設(shè)備上下文,用于在位圖上繪制
wx.RendererNative.Get().DrawPushButton(self.button, dc2, (0, 0, rect.width, rect.height), state) # 在位圖上繪制按鈕
dc.Blit(rect.x, rect.y, rect.width, rect.height, dc2, 0, 0, wx.COPY, True) # 將位圖復(fù)制到單元格上,覆蓋原有的內(nèi)容
# 在單元格中繪制標(biāo)簽
label = grid.GetTable().GetValue(row, col) # 獲取單元格的值
dc.DrawLabel(label, rect, wx.ALIGN_CENTER) # 在單元格中居中繪制標(biāo)簽
class ButtonEditor(wx.grid.GridCellEditor):
def __init__(self, button):
wx.grid.GridCellEditor.__init__(self) # 初始化GridCellEditor基類
self.button = button
self.SetControl(button)
def Create(self, parent, id, evtHandler):
pass
def BeginEdit(self, row, col, grid):
pass
def EndEdit(self, row, col, grid, oldVal):
pass
# 定義一個(gè)繼承自 wx.grid.Grid 的類 MyGrid
class MyGrid(wx.grid.Grid):
def __init__(self, parent):
# 調(diào)用 wx.grid.Grid 的初始化函數(shù)
wx.grid.Grid.__init__(self, parent, -1)
# 創(chuàng)建一個(gè) 3 行 3 列的網(wǎng)格
self.CreateGrid(3, 3)
# 設(shè)置第一列的標(biāo)題為 "Name"
self.SetColLabelValue(0, "Name")
# 設(shè)置第二列的標(biāo)題為 "Age"
self.SetColLabelValue(1, "Age")
# 設(shè)置第三列為空,即沒(méi)有標(biāo)題
self.SetColLabelValue(2, "")
# 在第3列的每一行中添加一個(gè)按鈕
for i in range(self.GetNumberRows()):
# 將第一列 Name 與 第二列 Age 填充 姓名與年齡
self.SetCellValue(i, 0, pn[i][0])
self.SetCellValue(i, 1, pn[i][1])
btn = wx.Button(self, id=i, label="Delete") # 創(chuàng)建一個(gè)名為 "Delete" 的按鈕,并綁定到 id=i 上
# 這兩行用上了前面派生的類
self.SetCellRenderer(i, 2, ButtonRenderer(btn)) # 在第 i 行的第 2 列中設(shè)置單元格渲染器為 ButtonRenderer(btn)
self.SetCellEditor(i, 2, ButtonEditor(btn)) # 在第 i 行的第 2 列中設(shè)置單元格編輯器為 ButtonEditor(btn)
self.SetCellValue(i, 2, "Delete") # 在第 i 行的第 2 列中設(shè)置單元格值為 "Delete" ,這一句沒(méi)有,會(huì)有顯示缺陷,可自
btn.Bind(wx.EVT_BUTTON, self.OnDeleteButtonClick) # 給按鈕綁定一個(gè)事件處理函數(shù) OndeletePlan
# 定義一個(gè)按鈕點(diǎn)擊事件處理函數(shù)
def OnDeleteButtonClick(self, event):
# 獲取按鈕所在的單元格的行號(hào),其實(shí)是按鈕的ID編號(hào)
row = event.GetId()
# 獲取單元格編輯器中的按鈕
aa: wx.Button = self.GetCellEditor(row, 2).button
# 解除按鈕的事件綁定,這個(gè)事件不解除,無(wú)法刪除這一行數(shù)據(jù)
aa.Unbind(wx.EVT_BUTTON)
# 刪除該行
self.DeleteRows(row)
class MyFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="My Grid")
self.grid = MyGrid(self)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.grid, 1, wx.EXPAND | wx.ALL, 5)
self.SetSizer(sizer)
self.Fit()
if __name__ == "__main__":
app = wx.App()
frame = MyFrame()
frame.Show()
app.MainLoop()
到此這篇關(guān)于wxPython中wx.gird.Gird添加按鈕的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)wxPython wx.gird.Gird添加按鈕內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python內(nèi)置函數(shù)int()用法簡(jiǎn)單介紹
這篇文章主要給大家介紹了關(guān)于Python內(nèi)置函數(shù)int()用法的相關(guān)資料,int()函數(shù)常用來(lái)把其他類型轉(zhuǎn)換為整數(shù),文中通過(guò)代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用python具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2024-05-05
從DataFrame中提取出Series或DataFrame對(duì)象的方法
今天小編就為大家分享一篇從DataFrame中提取出Series或DataFrame對(duì)象的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-11-11
python如何實(shí)現(xiàn)不可變字典inmutabledict
這篇文章主要介紹了python如何實(shí)現(xiàn)不可變字典inmutabledict,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-01-01
利用python實(shí)現(xiàn)萬(wàn)年歷的查詢
本篇文章主要給大家分享的是python實(shí)現(xiàn)萬(wàn)年歷的查詢,利用python做能夠?qū)崿F(xiàn)萬(wàn)年歷查詢的一個(gè)小功能,感興趣的小伙伴可以參考一下2021-10-10

