我正在尝试向网格单元添加按钮。我正在使用最新的演示4.0.7和python 3.7(32bit)我修复了一个旧示例,位于:https://groups.google.com/forum/#!topic/wxpython-users/HhtKCxPVX_s问题是按钮无法正常工作,然后按下它会导致整个网格消失。
class MyCustomRenderer2(gridlib.GridCellRenderer):
def __init__(self):
gridlib.GridCellRenderer.__init__(self)
self.down = False
self.click_handled = False
def Draw(self, grid, attr, dc, rect, row, col, isSelected):
"""This is called when the widget is Refreshed"""
print ('drawing button')
dc.Clear()
if self.down:
state = wx.CONTROL_PRESSED | wx.CONTROL_SELECTED
else:
state = 0
#if not self.IsEnabled():
# state = wx.CONTROL_DISABLED
#pt = self.ScreenToClient(wx.GetMousePosition())
#if self.GetClientRect().Contains(pt):
# state |= wx.CONTROL_CURRENT
wx.RendererNative.Get().DrawPushButton(grid, dc, rect, state)
#extra logic required since a button gets drawn at various times that could be while the mouse button is held down
if self.down and not self.click_handled:
self.click_handled = True
self.HandleClick()
def HandleClick(self):
print ('clicked')
def GetBestSize(self, grid, attr, dc, row, col):
text = grid.GetCellValue(row, col)
dc.SetFont(attr.GetFont())
w, h = dc.GetTextExtent(text)
return wx.Size(w, h)
def Clone(self):
return MyCustomRenderer2()
#!/usr/bin/python
# -*- coding: utf-8 -*-
# friendly coded by Laurent BEVILLE.
import wx
import wx.grid as gridlib
#---------------------------------------------------------------------------
class myFrame(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, parent, -1, size=(400, 300))
# ...
self.gridBox = wx.BoxSizer(wx.VERTICAL)
# ...
self.mainGrid = showGrid(self, numRows=5, numCols=5)
# ...
self.gridBox.Add(self.mainGrid)
self.SetSizerAndFit(self.gridBox)
class showGrid(gridlib.Grid):
def __init__(self, parent, numRows, numCols):
"""Constructeur"""
gridlib.Grid.__init__(self, parent, size=parent.GetSize())
self.CreateGrid(numRows, numCols)
self.SetRowLabelSize(50)
# Display content
self.displayContent()
# ...
self.handleEvents()
def displayContent(self):
self.rd = myRenderer(self)
# Button coordinates
self.rend_row = 2
self.rend_col = 1
# ...
self.SetCellValue(1, 0, 'Click on the Button')
# Set Button in cell
self.SetCellRenderer(self.rend_row, self.rend_col, self.rd)
# Prevent button cell selection
self.SetReadOnly(self.rend_row, self.rend_col, True)
def handleEvents(self):
self.Bind(gridlib.EVT_GRID_SELECT_CELL, self.onCellSelected)
def onCellSelected(self, event):
# # Button inverted switch var
switch_inv = {False: wx.CONTROL_NONE, True: wx.CONTROL_PRESSED}
# To avoid bug verify if it's possible to enable cell control
# Typical bug : "wx._core.wxAssertionError: C++ assertion "CanEnableCellControl()" failed at /home/...
# in EnableCellEditControl(): can't enable editing for this cell!"
if self.CanEnableCellControl():
self.EnableCellEditControl()
# Invert button status : CONTROL_NONE (inactive) / wx.CONTROL_PRESSED (active)
self.rd.buttonState = switch_inv[not self.rd.boolstat['boolstat']]
# Print button status
print("Button status : {0}".format({0:"inactive", 4:"active"}[self.rd.buttonState]))
class myRenderer(wx.grid.GridCellRenderer):
def __init__(self, parent):
wx.grid.GridCellRenderer.__init__(self)
# Button neutral state
self.boolstat = {'boolstat': True}
# Button state when initializing
self.buttonState = 0
def Draw(self, grid, attr, dc, rect, row, col, isSelected):
# Button switch var
switch = {wx.CONTROL_NONE: False, wx.CONTROL_PRESSED: True}
# Renderer state
self.boolstat['boolstat'] = switch[self.buttonState]
# ...
wx.RendererNative.Get().DrawPushButton(grid, dc, rect, self.buttonState)
#---------------------------------------------------------------------------
if __name__ == '__main__':
app = wx.App()
frame = myFrame(None)
frame.Show()
frame.Centre()
app.MainLoop()