网格内的Wxpython按钮

网格内的Wxpython按钮,wxpython,Wxpython,我正在尝试向网格单元格添加一个按钮我正在使用最新的演示版4.0.7和python 3.7(32位) 我修复了这里的一个旧示例: 问题是按钮工作不正常,按下按钮会导致整个网格消失 class MyCustomRenderer2(gridlib.GridCellRenderer): def __init__(self): gridlib.GridCellRenderer.__init__(self) self.down = False self.click_handled =

我正在尝试向网格单元格添加一个按钮
我正在使用最新的演示版4.0.7和python 3.7(32位)
我修复了这里的一个旧示例: 问题是按钮工作不正常,按下按钮会导致整个网格消失

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()

此脚本启动一个内部带有网格的框架。单击按钮时,外壳中会显示消息“active/inactive”。 关键是类通过使用两个开关变量(即两个反转的词汇)进行通信

导入wx
将wx.grid作为gridlib导入
#---------------------------------------------------------------------------
类myFrame(wx.Frame):
定义初始化(自身,父级):
wx.Frame.\uuuuu init\uuuuuux(self,parent,-1,size=(400300))
# ...
self.gridBox=wx.BoxSizer(wx.VERTICAL)
# ...
self.mainGrid=showGrid(self,numRows=5,numCols=5)
# ...
self.gridBox.Add(self.mainGrid)
self.setSizerAndFT(self.gridBox)
类showGrid(gridlib.Grid):
定义初始化(自、父、numRows、numCols):
“施工人员”
Grid.Grid.\uuuu init\uuuu(self,parent,size=parent.GetSize())
self.CreateGrid(numRows、numCols)
self.SetRowLabelSize(50)
#显示内容
self.displayContent()
# ...
self.handleEvents()
def显示内容(自我):
self.rd=myRenderer(self)
#按钮坐标
self.rend_行=2
self.rend_col=1
# ...
self.SetCellValue(1,0,'单击按钮')
#在单元格中设置按钮
self.SetCellRenderer(self.rend_行、self.rend_列、self.rd)
#防止按钮单元格选择
self.SetReadOnly(self.rend_行、self.rend_列、True)
def手柄通风口(自):
self.Bind(gridlib.EVT\u GRID\u SELECT\u CELL,self.onCellSelected)
def onCellSelected(自身、事件):
##按钮式倒闸var
开关_inv={False:wx.CONTROL_NONE,True:wx.CONTROL_PRESSED}
#为了避免错误,请验证是否可以启用单元控制
典型的错误:“Wx.O.Cord.WxRealEdrrist: C++断言”CabeNabeleCelpor()“在/home /…
#在EnableCellEditControl()中:无法为此单元格启用编辑!”
如果self.CanEnableCellControl():
self.EnableCellEditControl()
#反转按钮状态:控制按钮无(未激活)/wx。控制按钮按下(激活)
self.rd.buttonState=switch_inv[非self.rd.boolstat['boolstat']]
#打印按钮状态
打印(“按钮状态:{0}”。格式({0:“非活动”,4:“活动”}[self.rd.buttonState]))
类myRenderer(wx.grid.GridCellRenderer):
定义初始化(自身,父级):
grid.GridCellRenderer.\uuuu init\uuuuuu(self)
#按钮中性状态
self.boolstat={'boolstat':True}
#初始化时的按钮状态
self.buttonState=0
def Draw(自身、栅格、属性、dc、rect、row、col、isSelected):
#按钮开关var
开关={wx.CONTROL\u NONE:False,wx.CONTROL\u PRESSED:True}
#渲染器状态
self.boolstat['boolstat']=开关[self.buttonState]
# ...
wx.renderNative.Get().DrawButton(网格、dc、rect、self.buttonState)
#---------------------------------------------------------------------------
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
app=wx.app()
frame=myFrame(无)
frame.Show()
框架.中心()
app.MainLoop()

此脚本启动一个内部带有网格的框架。单击按钮时,外壳中会显示消息“active/inactive”。 关键是类通过使用两个开关变量(即两个反转的词汇)进行通信

导入wx
将wx.grid作为gridlib导入
#---------------------------------------------------------------------------
类myFrame(wx.Frame):
定义初始化(自身,父级):
wx.Frame.\uuuuu init\uuuuuux(self,parent,-1,size=(400300))
# ...
self.gridBox=wx.BoxSizer(wx.VERTICAL)
# ...
self.mainGrid=showGrid(self,numRows=5,numCols=5)
# ...
self.gridBox.Add(self.mainGrid)
self.setSizerAndFT(self.gridBox)
类showGrid(gridlib.Grid):
定义初始化(自、父、numRows、numCols):
“施工人员”
Grid.Grid.\uuuu init\uuuu(self,parent,size=parent.GetSize())
self.CreateGrid(numRows、numCols)
self.SetRowLabelSize(50)
#显示内容
self.displayContent()
# ...
self.handleEvents()
def显示内容(自我):
self.rd=myRenderer(self)
#按钮坐标
self.rend_行=2
self.rend_col=1
# ...
self.SetCellValue(1,0,'单击按钮')
#在单元格中设置按钮
self.SetCellRenderer(self.rend_行、self.rend_列、self.rd)
#防止按钮单元格选择
self.SetReadOnly(self.rend_行、self.rend_列、True)
def手柄通风口(自):
self.Bind(gridlib.EVT\u GRID\u SELECT\u CELL,self.onCellSelected)
def onCellSelected(自身、事件):
##按钮式倒闸var
开关_inv={False:wx.CONTROL_NONE,True:wx.CONTROL_PRESSED}
#为了避免错误,请验证是否可以启用单元控制
典型的错误:“Wx.O.Cord.WxRealEdrrist: C++断言”CabeNabeleCelpor()“在/home /…
#在EnableCellEditControl()中:无法为此单元格启用编辑!”
如果self.CanEnableCellControl():
self.EnableCellEditControl()
#反转按钮状态:控制按钮无(未激活)/wx。控制按钮按下(激活)
self.rd.buttonState=switch_inv[非self.rd.boolstat['boolstat']]
#打印按钮状态
打印(“按钮状态:{0}”。格式({0:“非活动”,4:“活动”}[self.rd.buttonState]))
类myRenderer(wx.grid.GridCellRenderer):
定义初始化(自身,父级):
grid.GridCellRenderer.\uuuu init\uuuuuu(self)
#按钮中性状态
选择
import wx
import wx.grid as Grid

class MyFrame(wx.Frame):
    def __init__(self, parent, title):
        super(MyFrame, self).__init__(parent, title=title, size=(400, 300))

        self.panel = MyPanel(self)
        self.MyGrid = New_Grid(self, numRows=2, numCols=5)
        mainSizer = wx.BoxSizer(wx.VERTICAL)
        mainSizer.Add(self.MyGrid,1,wx.ALL|wx.EXPAND,0)
        self.SetSizer(mainSizer)


class MyPanel(wx.Panel):
    def __init__(self, parent):
        super(MyPanel, self).__init__(parent)


class New_Grid(Grid.Grid):
    def __init__(self, parent, numRows, numCols):
        Grid.Grid.__init__(self, parent)

        self.CreateGrid(numRows, numCols)
        self.SetRowLabelSize(35)
        self.AutoSizeColumns(True)
        # Display content
        self.displayContent()
        # ...
        self.handleEvents()

    def displayContent(self):
        myList = [
            "Col1",
            "Col2",
            "Col3",
            "Col4",
            "Set"
        ]
        x = 0
        for item in myList:
            self.SetColLabelValue(x, item)
            x += 1
        self.SetColLabelSize(25)
        self.AutoSizeColumns(True)
        self.update_Grid()

    def handleEvents(self):
        self.Bind(Grid.EVT_GRID_SELECT_CELL, self.onCellSelected)

    def onCellSelected(self, event):
        col = event.GetCol()
        if col == 5:
            Selected = event.GetRow()

    def update_Grid(self):
        img = wx.Bitmap("SET.png", wx.BITMAP_TYPE_PNG)
        self.rd = MyImageRenderer(img)
        # Buttons coordinates
        numRows = self.GetNumberRows()
        for y in range(numRows):
            self.rd.rend_row = y
            self.rd.rend_col = 4
            self.SetCellRenderer(self.rd.rend_row, self.rd.rend_col, self.rd)
            self.SetColSize(0, img.GetWidth() + 2)
            self.SetRowSize(0, img.GetHeight() + 3)
            self.SetReadOnly(self.rd.rend_row, self.rd.rend_col, True)

class MyImageRenderer(wx.grid.GridCellRenderer):
    def __init__(self, img):
        wx.grid.GridCellRenderer.__init__(self)
        self.img = img

    def Draw(self, grid, attr, dc, rect, row, col, isSelected):
        image = wx.MemoryDC()
        image.SelectObject(self.img)
        dc.SetBackgroundMode(wx.SOLID)
        if isSelected:
            dc.SetBrush(wx.Brush(wx.BLUE, wx.SOLID))
            dc.SetPen(wx.Pen(wx.BLUE, 1, wx.SOLID))
        else:
            dc.SetBrush(wx.Brush(wx.WHITE, wx.SOLID))
            dc.SetPen(wx.Pen(wx.WHITE, 1, wx.SOLID))
        dc.DrawRectangle(rect)
        width, height = self.img.GetWidth(), self.img.GetHeight()
        if width > rect.width - 2:
            width = rect.width - 2
        if height > rect.height - 2:
            height = rect.height - 2
        dc.Blit(rect.x + 1, rect.y + 1, width, height, image, 0, 0, wx.COPY, True)

    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)


class MyApp(wx.App):
    def OnInit(self):
        self.frame = MyFrame(parent=None,title="wxPython Window")
        self.frame.Show()
        return True


app = MyApp()
app.MainLoop()