Hello,
I'm following the demo code for the Grid_MegaExample and I'm trying to
update the table with new data based on an event. What I want to happen
is for my keyword argument "_file" to change and then for the table to
update based on that new .txt file.
I get errors when I try to do an event-based change. The program
initializes fine. My big concern is to be able to dynamically change
the name of the text file, query MySQL, then see the new information.
I'm under the assumption that I only need to change my "_file" keyword
argument in the __init__ of my grid, which would then go back up to the
PyGridTableBase. What am I missing? Am I putting the event in the
wrong object (the Frame instead of the Grid)?
I put ALL of the code below so that there wouldn't be any confusion if
I omitted anything. Thanks in advance. ~Telly
···
____________________________________________________________________________
import wx
import wx.grid as gridlib
import MySQLdb
#---------------------------------------------------------------------------
class HugeTable(gridlib.PyGridTableBase):
def __init__(self, _host='localhost', _user='root',
_passwd='Shellie2', _port=3306, _db='music', _file='1hrdata.txt'):
gridlib.PyGridTableBase.__init__(self)
self.odd=gridlib.GridCellAttr()
self.odd.SetBackgroundColour("sky blue")
self.even=gridlib.GridCellAttr()
self.even.SetBackgroundColour("sea green")
self.db = MySQLdb.connect(host=_host, user=_user,
passwd=_passwd, port=_port, db=_db)
self.cursor = self.db.cursor()
self.data = _file
self.f = open(self.data, "r")
self.msg = self.f.read()
self.f.close()
self.cursor.execute(self.msg)
#data
self.sql = self.cursor.fetchall()
#column data
self.sql_columns = self.cursor.description
self._rows = self.GetNumberRows()
self._cols = self.GetNumberCols()
def GetAttr(self, row, col, kind):
attr = [self.even, self.odd][row % 2]
attr.IncRef()
return attr
# This is all it takes to make a custom data table to plug into a
# wxGrid. There are many more methods that can be overridden, but
# the ones shown below are the required ones. This table simply
# provides strings containing the row and column values.
def GetNumberRows(self):
return len(self.sql)
def GetNumberCols(self):
return len(self.sql_columns[0])
def IsEmptyCell(self, row, col):
return False
def GetValue(self, row, col):
return self.sql[row][col]
def SetValue(self, row, col, value):
self.sql[row][col] = value
def GetColLabelValue(self, col):
return str(self.sql_columns[col][0])
def ResetView(self, grid):
grid.BeginBatch()
for current, new, delmsg, addmsg in [
(self._rows, self.GetNumberRows(),
gridlib.GRIDTABLE_NOTIFY_ROWS_DELETED,
gridlib.GRIDTABLE_NOTIFY_ROWS_APPENDED),
(self._cols, self.GetNumberCols(),
gridlib.GRIDTABLE_NOTIFY_COLS_DELETED,
gridlib.GRIDTABLE_NOTIFY_COLS_APPENDED),
]:
if new < current:
msg = gridlib.GridTableMessage(self, delmsg, new,
current-new)
grid.ProcessTableMessage(msg)
elif new > current:
msg = gridlib.GridTableMessage(self, addmsg, new-current)
grid.ProcessTableMessage(msg)
self.UpdateValues(grid)
grid.EndBatch()
self._rows = self.GetNumberRows()
self._cols = self.GetNumberCols()
#update the scrollbars and the displayed part of the grid
grid.AdjustScrollbars()
grid.ForceRefresh()
def UpdateValues(self, grid):
"""Update all displayed values"""
#This sends an event to the grid table to update all of the values
msg = Grid.GridTableMessage(self,
Grid.GRIDTABLE_REQUEST_VIEW_GET_VALUES)
grid.ProcessTableMessage(msg)
#---------------------------------------------------------------------------
class HugeTableGrid(gridlib.Grid):
def __init__(self, parent, _host='localhost', _user='root',
_passwd='Shellie2', _port=3306, _db='music',
_file='1hrdata.txt'):
gridlib.Grid.__init__(self, parent, -1)
self.table = HugeTable(_host, _user, _passwd, _port, _db, _file)
# The second parameter means that the grid is to take ownership
of the
# table and will destroy it when done. Otherwise you would need
to keep
# a reference to it and call it's Destroy method later.
self.SetTable(self.table, True)
self.AutoSize()
def Reset(self):
"""reset the view based on the data in the table. Call
this when rows are added or destroyed"""
self.table.ResetView(self)
#---------------------------------------------------------------------------
class TestFrame(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, wx.DefaultPosition,
wx.Size(750, 500))
self.Centre()
menubar = wx.MenuBar()
menufile = wx.Menu()
edit = wx.Menu()
help = wx.Menu()
menufile.Append(101, "&Refresh", "Refresh the grid.")
menufile.AppendSeparator()
quit = wx.MenuItem(menufile, 102, "&Quit", "Quit the program.")
quit.SetBitmap(wx.Image('stock_exit-16.png',
wx.BITMAP_TYPE_PNG).ConvertToBitmap())
menufile.AppendItem(quit)
wx.EVT_MENU(self, 102, self.OnQuit)
edit.Append(201, 'check test', '', wx.ITEM_RADIO)
edit.Append(202, 'check test', '', kind = wx.ITEM_CHECK)
submenu = wx.Menu()
submenu.Append(301, 'radio test', kind=wx.ITEM_RADIO)
edit.AppendMenu(203, 'submenu', submenu)
menubar.Append(menufile, "&File")
menubar.Append(edit, "&Edit")
menubar.Append(help, "&Help")
self.SetMenuBar(menubar)
self.statusbar = wx.StatusBar(self)
self.statusbar.SetFieldsCount(2)
widths = [-2, -1]
self.statusbar.SetStatusWidths(widths)
self.SetStatusBar(self.statusbar)
self.statusbar.SetStatusText("10 Songs", 1)
splitter1 = wx.SplitterWindow(self, style = wx.SUNKEN_BORDER |
wx.CLIP_CHILDREN)
self.splitter2 = wx.SplitterWindow(splitter1, style =
wx.SUNKEN_BORDER | wx.CLIP_CHILDREN)
panel = wx.Panel(self.splitter2, -1, style = wx.NO_BORDER)
self.treectrl = wx.TreeCtrl(splitter1, 1)
root = self.treectrl.AddRoot('Sets')
one_hr = self.treectrl.AppendItem(root, '1 Hour Set')
two_hr = self.treectrl.AppendItem(root, '2 Hour Set')
self.treectrl.AppendItem(one_hr, 'A')
self.treectrl.AppendItem(one_hr, 'B')
self.treectrl.AppendItem(two_hr, 'A')
self.treectrl.AppendItem(two_hr, 'B')
self.treectrl.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnSelChanged, id=1)
self.grid = HugeTableGrid(self.splitter2)
self.grid.Reset()
self.splitter2.SplitHorizontally(panel, self.grid, -300)
splitter1.SplitVertically(self.treectrl, self.splitter2, 120)
splitter1.SetMinimumPaneSize(20)
self.splitter2.SetMinimumPaneSize(20)
self.SetIcon(wx.Icon('tipi.ico', wx.BITMAP_TYPE_ICO))
def OnQuit(self, event):
self.Close()
def OnSelChanged(self, event):
self.grid = HugeTable(self, _file='2hrdataa.txt')
self.grid.Reset()
#---------------------------------------------------------------------------
if __name__ == '__main__':
app = wx.App()
frame = TestFrame(None, -1, 'DJ Suite')
frame.Show(True)
app.MainLoop()