Solution to: pyGridTableBase & MySQL Data

Hey everyone,

  I've been working on the problem with getting new data into the wx.grid
when I want new information from MySQL. I found a solution that works
for me, for now. I'm not a good programmer, but I thought I'd pass
along this bit of info on the solution I found. I'd love to put this
into the documentation, but it gets this error whenever I click my
OnClick button:

#----------BEGIN ERROR MESSAGE----------------

Traceback (most recent call last):
  File "C:\Python24\Programs\DJSuite\wxgridcopy.py", line 166, in OnClick
    self.grid.AutoSize()
  File "C:\Python24\lib\site-packages\wx-2.6-msw-ansi\wx\_core.py", line
13485, in __getattr__
    raise PyDeadObjectError(self.attrStr % self._name)
wx._core.PyDeadObjectError: The C++ part of the Grid object has been
deleted, attribute access no longer allowed.

#---------END ERROR MESSAGE--------------------

  I'm still trying to figure out what this all means...=)

  Anyways, here's the code. If anyone figures out a better way, please
let us all know, as will I. Again, if someone thinks that this is worth
posting (even with the error), let me know. Bye!

#---------BEGIN CODE---------------------------

import wx
import wx.grid
import getdataall
import getdata1hr
db = getdata1hr.Eb_db()
db2 = getdataall.Eb_db()

class LineupTable(wx.grid.PyGridTableBase):
    def __init__(self):
        wx.grid.PyGridTableBase.__init__(self)

        #---Grid cell attributes

        self.odd = wx.grid.GridCellAttr()
        self.odd.SetBackgroundColour("grey")
        self.odd.SetFont(wx.Font(8, wx.SWISS, wx.NORMAL, wx.BOLD))

        self.even = wx.grid.GridCellAttr()
        self.even.SetBackgroundColour("white")
        self.even.SetFont(wx.Font(8, wx.SWISS, wx.NORMAL, wx.BOLD))

    #---Mandatory constructors for grid

    def GetNumberRows(self):
        return len(db.data)

    def GetNumberCols(self):
        return len(db.fields)

    def GetColLabelValue(self, col):
        return db.fields[col][0]

    def IsEmptyCell(self, row, col):
        if db.data[row][col] == "" or db.data[row][col] is None:
            return True
        else:
            return False

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

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

    def GetAttr(self, row, col, kind):
        attr = [self.even, self.odd][row % 2]
        attr.IncRef()
        return attr

#--------NEW GRID DATA

class LineupTable2(wx.grid.PyGridTableBase):
    def __init__(self):
        wx.grid.PyGridTableBase.__init__(self)

        #---Grid cell attributes

        self.odd = wx.grid.GridCellAttr()
        self.odd.SetBackgroundColour("grey")
        self.odd.SetFont(wx.Font(8, wx.SWISS, wx.NORMAL, wx.BOLD))

        self.even = wx.grid.GridCellAttr()
        self.even.SetBackgroundColour("white")
        self.even.SetFont(wx.Font(8, wx.SWISS, wx.NORMAL, wx.BOLD))

    #---Mandatory constructors for grid

    def GetNumberRows(self):
        return len(db2.data)

    def GetNumberCols(self):
        return len(db2.fields)

    def GetColLabelValue(self, col):
        return db2.fields[col][0]

    def IsEmptyCell(self, row, col):
        if db2.data[row][col] == "" or db2.data[row][col] is None:
            return True
        else:
            return False

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

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

    def GetAttr(self, row, col, kind):
        attr = [self.even, self.odd][row % 2]
        attr.IncRef()
        return attr

    #---Create frame

class MyFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, parent=None, id=-1, title='DJ Sets',
                          size=(900, 300))

        #---Panel

        self.panel = wx.ScrolledWindow(self, -1, style=wx.HSCROLL |
wx.VSCROLL)
        self.panel.SetScrollbars(20, 150, 100, 100)

        #---Buttons

        self.btn_1hr = wx.Button(self.panel, -1, "1-Hour Set", pos=(10,
10), size=wx.DefaultSize)
        self.Bind(wx.EVT_BUTTON, self.OnClick, self.btn_1hr)

        self.btn_2hr = wx.Button(self.panel, -1, "2-Hour Set", pos=(10,
35), size=wx.DefaultSize)

        self.btn_3hr = wx.Button(self.panel, -1, "3-Hour Set", pos=(10,
60), size=wx.DefaultSize)

        self.btn_4hr = wx.Button(self.panel, -1, "4-Hour Set", pos=(10,
85), size=wx.DefaultSize)

        #---Grid

        self.grid = wx.grid.Grid(self.panel, pos=(140, 0), size=(900, 300))

        self.table = LineupTable()
        self.grid.SetTable(self.table, True)

        #---Grid properties

        self.grid.EnableEditing(False)
        self.grid.SetDefaultCellAlignment(wx.ALIGN_CENTER, wx.ALIGN_CENTER)
        self.grid.SetSelectionBackground('red')
        self.grid.EnableDragColSize(enable=False)
        self.grid.EnableDragRowSize(enable=False)
        self.grid.SetLabelBackgroundColour((100, 200, 150))
        self.grid.SetLabelTextColour((255, 255, 255))

        #---Column Sizes

        self.grid.AutoSize()

        #---Use below if want to size individual columns (index, size)
        #---Also have SetRowSize
        #grid.SetColSize(0, 150)

    def OnClick(self, event):
        self.grid.Destroy()
        self.grid2 = wx.grid.Grid(self.panel,pos=(140, 0), size=(900, 300))
        self.table2 = LineupTable2()
        self.grid2.SetTable(self.table2)
        self.grid2.EnableEditing(False)
        self.grid2.SetDefaultCellAlignment(wx.ALIGN_CENTER, wx.ALIGN_CENTER)
        self.grid2.SetSelectionBackground('red')
        self.grid2.EnableDragColSize(enable=False)
        self.grid2.EnableDragRowSize(enable=False)
        self.grid2.SetLabelBackgroundColour((100, 200, 150))
        self.grid2.SetLabelTextColour((255, 255, 255))
        self.grid2.AutoSize()

        #---Column Sizes

        self.grid.AutoSize()
        self.grid.ForceRefresh()

if __name__ == "__main__":
    app = wx.PySimpleApp()
    frame = MyFrame()
    frame.Show()
    app.MainLoop()

#----------END CODE--------------------------

Hi Telly,

Telly Williams wrote:

Hey everyone,

  I've been working on the problem with getting new data into the wx.grid
when I want new information from MySQL. I found a solution that works
for me, for now. I'm not a good programmer, but I thought I'd pass
along this bit of info on the solution I found. I'd love to put this
into the documentation, but it gets this error whenever I click my
OnClick button:

#----------BEGIN ERROR MESSAGE----------------

Traceback (most recent call last):
  File "C:\Python24\Programs\DJSuite\wxgridcopy.py", line 166, in OnClick
    self.grid.AutoSize()
  File "C:\Python24\lib\site-packages\wx-2.6-msw-ansi\wx\_core.py", line
13485, in __getattr__
    raise PyDeadObjectError(self.attrStr % self._name)
wx._core.PyDeadObjectError: The C++ part of the Grid object has been
deleted, attribute access no longer allowed.
  

Your first line of OnClick destroys self.grid and then later on you do self.grid.AutoSize() but at that time self.grid is no longer there and therefore you get the PyDeadObjectError.

Have you seen the wiki pages on this?

http://wiki.wxpython.org/index.cgi/UpdatingGridData?highlight=(grid)

Werner

You might want to take a look at Dabo and how data is integrated into the grid. If you really want to do it all by hand yourself, you can look at the code in the dGrid class to see how we did it. Or you might simply want to try Dabo yourself, and get your application up and running instead of trying to decipher the intricacies of wxPython. It would take a couple of lines of code to create a simple business object that connects to MySQL and handles your queries, and setting a handful of properties to link the grid and its columns to that bizobj. We have several screencasts that show some of the tools that come with Dabo to make this process even easier:

Populating a Grid Using Business Objects
http://leafe.com/screencasts/populategrid.html

Create a Database Application in Less Than a Minute
http://leafe.com/screencasts/appwizard.html

Building a Database Application using the Dabo Class Designer (Parts 1 & 2)
http://leafe.com/screencasts/dataenvironment1.html
http://leafe.com/screencasts/dataenvironment2.html

-- Ed Leafe
-- http://leafe.com
-- http://dabodev.com

···

On Feb 3, 2007, at 3:29 AM, Telly Williams wrote:

I've been working on the problem with getting new data into the wx.grid
when I want new information from MySQL. I found a solution that works
for me, for now. I'm not a good programmer, but I thought I'd pass
along this bit of info on the solution I found. I'd love to put this
into the documentation, but it gets this error whenever I click my
OnClick button: