Hello.
I am making a program that interacts with MySQL database/table. I ran into 2 problems. The first one is about saving data which user entered into cell/or edited existing data in cell. The second problem is about inserting new row. Row is inserted, but it still shows error in background.
Problem number 1 error:
TypeError: OnCellChange() takes exactly 3 arguments (2 given)
Problem number 2 error:
self.data.append((str(row), '', '', '', '', '', '', '', ''))
NameError: global name 'row' is not defined
Here is the code:
import wx
import wx.grid as gridlib
import MySQLdb
import datetime
#Main Grid Class
class MyGrid(gridlib.Grid):
def __init__(self, parent):
gridlib.Grid.__init__(self, parent, )
#-----------------------------------MySQLdb---------------------------------------------------------------------------------------------------------------
# Get data
def getData():
db = MySQLdb.connect("127.0.0.1", "user", "password", "database")
cursor = db.cursor()
query = "SELECT * FROM setup"
cursor.execute(query)
data = []
res = cursor.fetchall()
for i in res:
data.append(i)
return data
#Update table
def updateTable(idSetup, colname, value):
db = MySQLdb.connect("127.0.0.1", "user", "password", "database")
cursor = db.cursor()
# sql upit
sql = "UPDATE setup SET " + colname + " = '" + str(value) + "' WHERE idSetup = " + str(idSetup) + ";"
# izvrsavanje upita
cursor.execute(sql)
db.commit()
db.disconnect()
#Insert data
def insert(data):
db = MySQLdb.connect("127.0.0.1", "user", "password", "database")
cursor = db.cursor()
# sql upit
sql = "INSERT INTO setup(idKomitent, Drzava, Prg, Provajder, ServerName, DataBaseName, Sifarnici, Promena) VALUES (%s, %s, %s, %s, %s, %s, %s, %s);"
# izvrsavanje upita
cursor.execute(sql, data)
db.commit()
sql = "SELECT LAST_INSERT_ID()"
cursor.execute(sql)
result = cursor.fetchall()[0][0]
db.disconnect()
return result
#Delete data
def delete(idSetup):
db = MySQLdb.connect("127.0.0.1", "user", "password", "database")
cursor = db.cursor()
# sql upit
sql = "DELETE FROM setup WHERE idSetup = " + str(idSetup) + ";"
# izvrsavanje upita
cursor.execute(sql)
db.commit()
db.disconnect()
# -----------------------------------MySQLdb---------------------------------------------------------------------------------------------------------------
#Column names
colnames = ["idSetup", "idKomitent", "Drzava", "Prg", "Provajder", "ServerName", "DataBaseName", "Sifarnici",
"Promena"]
#Setup
data = getData()
plugins = None
self.data = data
self.colnames = colnames
self.plugins = plugins or {}
#Number of row
def GetNumberRed(self):
return int(len(self.data))
def GetNumberRows(self):
return len(self.data)
#Number of columns
def GetNumberCols(self):
return int(len(self.colnames))
#Grid setup
col = GetNumberCols(self)
row = GetNumberRed(self)
self.CreateGrid(row, col)
self.ChangedValue = False
self.EnableEditing(True)
self.EnableGridLines(True)
self.EnableDragGridSize(False)
self.SetMargins(0, 0)
self.inner_sizer = wx.BoxSizer(wx.VERTICAL)
self._rows = self.GetNumberRows()
self._cols = self.GetNumberCols()
#Column names
self.SetColLabelValue(0, "idSetup")
self.SetColLabelValue(1, "idKomitent")
self.SetColLabelValue(2, "Drzava")
self.SetColLabelValue(3, "Prg")
self.SetColLabelValue(4, "Provajder")
self.SetColLabelValue(5, "ServerName")
self.SetColLabelValue(6, "DataBaseName")
self.SetColLabelValue(7, "Sifarnici")
self.SetColLabelValue(8, "Promena")
# Columns
self.EnableDragColMove(False)
self.EnableDragColSize(True)
self.SetColLabelSize(30)
self.SetColLabelAlignment(wx.ALIGN_CENTER, wx.ALIGN_CENTER)
# Cell Defaults
self.SetDefaultCellAlignment(wx.ALIGN_LEFT, wx.ALIGN_TOP)
self.inner_sizer.Add(self, 1, wx.ALL | wx.EXPAND, 5)
#Resize of table
self.SetSizer(self.inner_sizer)
self.Layout()
self.inner_sizer.Fit(self)
self.Bind(wx.EVT_SIZE, self.OnSize)
#Populating grid whit data from MySQL DB
for i, seq in enumerate(data):
for j, v in enumerate(seq):
if isinstance(v, (int, long,)):
v = str(v)
elif isinstance(v, datetime.datetime):
v = v.strftime('%d-%m-%Y')
try:
self.SetCellValue(i, j, v)
except TypeError:
raise RuntimeError(('SetCellValue failed with TypeError', i, j, v))
def GetValue(self, row, col):
return str(self.data[row][1].get(self.GetColLabelValue(col), ""))
def GetRawValue(self, row, col):
return self.data[row][1].get(self.GetColLabelValue(col), "")
def SetValue(self, row, col, value):
self.data[row][1][self.GetColLabelValue(col)] = value
#Events
self.Bind(wx.EVT_KEY_DOWN, self.onKeyDown)
self.Bind(gridlib.EVT_GRID_CELL_CHANGE, self.OnCellChange)
# Problem number 1 ---------#---------#---------#---------
#Here I want to save user imput from cells, which is achieved either by editing cell or entering new data in a new row
def OnCellChange(self, evt, data):
if (evt.GetRow() == self.GetNumberRows() - 2) and (evt.GetCol() == 1):
self.ChangedValue = True
else:
evt.Skip()
#---------#---------#---------#---------
#Enter key event
def onKeyDown(self, evt):
if evt.GetKeyCode() != wx.WXK_RETURN:
evt.Skip()
return
if evt.ControlDown(): # the edit control needs this key
evt.Skip()
return
self.DisableCellEditControl()
success = self.MoveCursorRight(evt.ShiftDown())
if not success:
newRow = self.GetGridCursorRow() + 1
if newRow < self.GetTable().GetNumberRows():
self.SetGridCursor(newRow, 0)
self.MakeCellVisible(newRow, 0)
else:
newRow = self.GetGridCursorRow() + 1
self.appendRow()
self.SetGridCursor(newRow, 0)
self.MakeCellVisible(newRow, 0)
self.ChangedValue = False
#Adding new row
def Reset(self):
"""reset the view based on the data in the table. Call
this when rows are added or destroyed"""
self.ResetView(self)
self.ro_attr = gridlib.GridCellAttr()
self.ro_attr.SetReadOnly(True)
self.SetRowAttr(self.GetNumberRows() - 1,self.ro_attr)
self.ro_attr = gridlib.GridCellAttr()
self.ro_attr.SetReadOnly(False)
self.SetRowAttr(self.GetNumberRows() - 2,self.ro_attr)
def ResetView(self, grid):
"""
(Grid) -> Reset the grid view. Call this to
update the grid if rows and columns have been added or deleted
"""
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 column rendering plugins
self._updateColAttrs(grid)
# 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 = gridlib.GridTableMessage(self, gridlib.GRIDTABLE_REQUEST_VIEW_GET_VALUES)
grid.ProcessTableMessage(msg)
def _updateColAttrs(self, grid):
"""
wx.Grid -> update the column attributes to add the
appropriate renderer given the column name. (renderers
are stored in the self.plugins dictionary)
Otherwise default to the default renderer.
"""
col = 0
for colname in self.colnames:
attr = gridlib.GridCellAttr()
if colname in self.plugins:
renderer = self.plugins[colname](self)
if renderer.colSize:
grid.SetColSize(col, renderer.colSize)
if renderer.rowSize:
grid.SetDefaultRowSize(renderer.rowSize)
# attr.SetReadOnly(True)
attr.SetRenderer(renderer)
grid.SetColAttr(col, attr)
col += 1
# Problem number 2 ---------#---------#---------#---------
# PyCharm repot that there is "Unresolved referenc 'row'"
def appendRow(self):
self.AppendRows(1)
self.data.append((str(row), '', '', '', '', '', '', '', ''))
self.Reset()
# ---------#---------#---------
#Resize grid
def OnSize(self, event):
width, height = self.GetClientSizeTuple()
for col in range (9):
self.SetColSize(col, width/(9 + 1))
#-----------------------------------------------------------------------------------------------------------------------
#Main Window class
class GlavniProzor(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, parent=None, title = "Editor", size = (500, 1000))
self.Show()
self.CenterOnScreen()
#Panel
panel = wx.Panel(self)
mygrid = MyGrid(panel)
#Box
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(mygrid, 1, wx.EXPAND|wx.ALL)
panel.SetSizer(sizer)
sizer.Fit(self)
#Run
if __name__ == "__main__":
app = wx.App()
frame = GlavniProzor()
app.MainLoop()
Anyone have any idea how to solve this.
Thank you.