I cannot make new values show in a grid cell, even though ForceRefresh() is called.

Hi Raffaello,

Thanks for the prompt answer.

I fixed the syntax error you mentioned, so - now you can see the real problem, namely, running the script and typing ‘www’ and in the top left cell, produces:

$ python ./DemoGridGeneric.py
row== 0 ;col== 0 ;old_val== Bob ;new_val== Bob ;new== WWW

But the grid still shows the original value ‘Bob’ on the screen.

The fixed program is below.

Bye,
Ron.

···

#!/usr/bin/env python

import wx
import wx.grid
import string

data = ((“Bob”, “Dernier”), (“Ryne”, “Sandberg”),
(“Gary”, “Matthews”), (“Leon”, “Durham”),
(“Keith”, “Moreland”), (“Ron”, “Cey”),
(“Jody”, “Davis”), (“Larry”, “Bowa”),
(“Rick”, “Sutcliffe”))

colLabels = (“Last”, “First”)
rowLabels = (“CF”, “2B”, “LF”, “1B”, “RF”, “3B”, “C”, “SS”, “P”)

class SimpleGrid(wx.grid.Grid):
def init(self, parent):
wx.grid.Grid.init(self, parent, -1)
tableBase = GenericTable(data, rowLabels, colLabels)
self.SetTable(tableBase)

class TestFrame(wx.Frame):
def init(self, parent):
wx.Frame.init(self, parent, -1, “ForceRefresh() working ?”,
size=(275, 275))
self.grid = SimpleGrid(self)
self.BindTableEvents()
self.grid.SetDefaultEditor(UpCaseCellEditor())
self.grid.AutoSize()

def OnGridCellChange(self, evt):
    row,col = evt.GetRow(),evt.GetCol()
    old_val = self.grid.GetTable().GetValue(row,col)
    new = self.grid.__dict__["changed_val"]
    self.grid.SetCellValue(row,col,new)
    self.grid.ForceRefresh()
    new_val = self.grid.GetTable().GetValue(row,col)
    print "row==",row,";col==",col,";old_val==",old_val,";new_val==",new_val,";new==",new

def BindTableEvents(self):
    self.Bind(event=wx.grid.EVT_GRID_CELL_CHANGE, handler=self.OnGridCellChange, source=None)

def SetDefaultCellEditor(self,grid):
    self.editor = grid.SetDefaultEditor(grid_editor.UpCaseCellEditor())

class UpCaseCellEditor(wx.grid.PyGridCellEditor):
def init(self):
wx.grid.PyGridCellEditor.init(self)

def Create(self, parent, id, evtHandler):
    self._tc = wx.TextCtrl(parent, id, "")
    self._tc.SetInsertionPoint(0)
    self.SetControl(self._tc)

    if evtHandler:
        self._tc.PushEventHandler(evtHandler)

    self._tc.Bind(wx.EVT_CHAR, self.OnChar)

def SetSize(self, rect):
    self._tc.SetDimensions(rect.x, rect.y, rect.width+2, rect.height+2,
                           wx.SIZE_ALLOW_MINUS_ONE)

def BeginEdit(self, row, col, grid):
    self.startValue = grid.GetTable().GetValue(row, col)
    self._tc.SetValue(self.startValue)
    self._tc.SetInsertionPointEnd()
    self._tc.SetFocus()
    self._tc.SetSelection(0, self._tc.GetLastPosition())

def EndEdit(self, row, col, grid):
    changed = False

    val = self._tc.GetValue()
   
    if val != self.startValue:
        changed = True
        grid.GetTable().SetValue(row, col, val)
        """
        The contents of 'val', could be retrieved from outside
        as: self.grid.__dict__["changed_val"]
        """
        grid.changed_val = val

    self.startValue = ''
    self._tc.SetValue('')

    return changed

def Reset(self):
    self._tc.SetValue(self.startValue)
    self._tc.SetInsertionPointEnd()

def Clone(self):
    return UpCaseCellEditor()

def StartingKey(self, evt):
    self.OnChar(evt)
    if evt.GetSkipped():
        self._tc.EmulateKeyPress(evt)

def OnChar(self, evt):
    key = evt.GetKeyCode()
    if key > 255:
        evt.Skip()
        return
    char = chr(key)
    if char in string.letters:
        char = char.upper()
        self._tc.WriteText(char)
    else:
        evt.Skip()

class GenericTable(wx.grid.PyGridTableBase):

def __init__(self, data, rowLabels=None, colLabels=None):
    wx.grid.PyGridTableBase.__init__(self)
    self.data = data
    self.rowLabels = rowLabels
    self.colLabels = colLabels
   
def GetNumberRows(self):
    try:
        return len(self.data)
    except (TypeError):
        pass
def GetNumberCols(self):
    try:
        return len(self.data[0])
    except:
        pass

def GetColLabelValue(self, col):
    if self.colLabels:
        return self.colLabels[col]

def IsEmptyCell(self, row, col):
    return False
def GetValue(self, row, col):
    try:
        return self.data[row][col]
    except:
        pass

def SetValue(self, row, col, value):
    pass        

if name == ‘main’:
app = wx.PySimpleApp()
frame = TestFrame(None)
frame.Show(True)
app.MainLoop()


Message: 1
Date: Wed, 20 Aug 2008 13:10:29 +0200
From: raffaello barbarossa.platz@gmail.com
Subject: Re: [wxpython-users] Re: I cannot make new values show in a
grid cell, even though ForceRefresh() is called.
To: wxpython-users@lists.wxwidgets.org
Message-ID:
5caf8fc00808200410u2e57552bke9f82b15fa04a8b1@mail.gmail.com
Content-Type: text/plain; charset=“iso-8859-1”

You just misplaced a line, the function should read

def OnGridCellChange(self, evt):
    row,col =3D evt.GetRow(),evt.GetCol()
    old_val =3D self.grid.GetTable().GetValue(row,col)

    *new_val =3D self.grid.GetTable().GetValue(**row,col)*

    new =3D self.grid.__dict__["changed_val"]
    self.grid.SetCellValue(row,col,new_val)
    self.grid.ForceRefresh()

    print

“row=3D=3D”,row,“;col=3D=3D”,col,“;old_val=3D=3D”,old_val,“;new_val=3D=3D”,=
new_val,“;new=3D=3D”,new

I wonder why the stdout did not tell you that. I received at once the following error message:

C:/Python25/pythonw.exe -u “C:/Python_programs/Guests/GridNotWorking.py”
Traceback (most recent call last):
File “C:/Python_programs/Guests/GridNotWorking.py”, line 37, in OnGridCellChange
self.grid.SetCellValue(row,col,new_val)
UnboundLocalError: local variable ‘new_val’ referenced before assignment

So long

2008/8/20 Barak, Ron Ron.Barak@lsi.com

Hi Raffaello,

Sorry it took me awhile to create a demo of my post of 2008.08.17: “I
*
cannot* make new values show in a grid cell, even *
though* ForceRefresh() is called.” as requested.

Below is the program, with the ‘offending’ function:

def OnGridCellChange(self, evt):
    row,col =3D evt.GetRow(),evt.GetCol()
    old_val =3D self.grid.GetTable().GetValue(row,col)
    new =3D self.grid.__dict__["changed_val"]
    self.grid.SetCellValue(row,col,new_val)
    self.grid.ForceRefresh()
    new_val =3D self.grid.GetTable().GetValue(row,col)
    print

“row=3D=3D”,row,“;col=3D=3D”,col,“;old_val=3D=3D”,old_val,“;new_val=3D
=3D=
“,new_val,”;new=3D=3D”,new
Where the print line demonstrate that the value is changed, but the
grid itself is not updated on the screen (in spite of
self.grid.ForceRefresh()) .

Any suggestions would be welcome.

Bye,
Ron.


#!/usr/bin/env python

import wx
import wx.grid
import string

data =3D ((“Bob”, “Dernier”), (“Ryne”, “Sandberg”),
(“Gary”, “Matthews”), (“Leon”, “Durham”),
(“Keith”, “Moreland”), (“Ron”, “Cey”),
(“Jody”, “Davis”), (“Larry”, “Bowa”),
(“Rick”, “Sutcliffe”))

colLabels =3D (“Last”, “First”)
rowLabels =3D (“CF”, “2B”, “LF”, “1B”, “RF”, “3B”, “C”, “SS”, “P”)

class SimpleGrid(wx.grid.Grid):
def init(self, parent):
wx.grid.Grid.init(self, parent, -1)
tableBase =3D GenericTable(data, rowLabels, colLabels)
self.SetTable(tableBase)

class TestFrame(wx.Frame):
def init(self, parent):
wx.Frame.init(self, parent, -1, “ForceRefresh() working ?”,
size=3D(275, 275))
self.grid =3D SimpleGrid(self)
self.BindTableEvents()
self.grid.SetDefaultEditor(UpCaseCellEditor())
self.grid.AutoSize()

def OnGridCellChange(self, evt):
    row,col =3D evt.GetRow(),evt.GetCol()
    old_val =3D self.grid.GetTable().GetValue(row,col)
    new =3D self.grid.__dict__["changed_val"]
    self.grid.SetCellValue(row,col,new_val)
    self.grid.ForceRefresh()
    new_val =3D self.grid.GetTable().GetValue(row,col)
    print

“row=3D=3D”,row,“;col=3D=3D”,col,“;old_val=3D=3D”,old_val,“;new_val=3D
=3D=
“,new_val,”;new=3D=3D”,new

def BindTableEvents(self):
    self.Bind(event=3Dwx.grid.EVT_GRID_CELL_CHANGE,

handler=3Dself.OnGridCellChange, source=3DNone)

def SetDefaultCellEditor(self,grid):
    self.editor =3D

grid.SetDefaultEditor(grid_editor.UpCaseCellEdito=
r())

class UpCaseCellEditor(wx.grid.PyGridCellEditor):
def init(self):
wx.grid.PyGridCellEditor.init(self)

def Create(self, parent, id, evtHandler):
    self._tc =3D wx.TextCtrl(parent, id, "")
    self._tc.SetInsertionPoint(0)
    self.SetControl(self._tc)

    if evtHandler:
        self._tc.PushEventHandler(evtHandler)

    self._tc.Bind(wx.EVT_CHAR, self.OnChar)

def SetSize(self, rect):
    self._tc.SetDimensions(rect.x, rect.y, rect.width+2,

rect.height+=
2,
wx.SIZE_ALLOW_MINUS_ONE)

def BeginEdit(self, row, col, grid):
    self.startValue =3D grid.GetTable().GetValue(row, col)
    self._tc.SetValue(self.startValue)
    self._tc.SetInsertionPointEnd()
    self._tc.SetFocus()
    self._tc.SetSelection(0, self._tc.GetLastPosition())

def EndEdit(self, row, col, grid):
    changed =3D False

    val =3D self._tc.GetValue()

    if val !=3D self.startValue:
        changed =3D True
        grid.GetTable().SetValue(row, col, val)
        """
        The contents of 'val', could be retrieved from outside
        as: self.grid.__dict__["changed_val"]
        """
        grid.changed_val =3D val

    self.startValue =3D ''
    self._tc.SetValue('')

    return changed

def Reset(self):
    self._tc.SetValue(self.startValue)
    self._tc.SetInsertionPointEnd()

def Clone(self):
    return UpCaseCellEditor()

def StartingKey(self, evt):
    self.OnChar(evt)
    if evt.GetSkipped():
        self._tc.EmulateKeyPress(evt)

def OnChar(self, evt):
    key =3D evt.GetKeyCode()
    if key > 255:
        evt.Skip()
        return
    char =3D chr(key)
    if char in string.letters:
        char =3D char.upper()
        self._tc.WriteText(char)
    else:
        evt.Skip()

class GenericTable(wx.grid.PyGridTableBase):

def __init__(self, data, rowLabels=3DNone, colLabels=3DNone):
    wx.grid.PyGridTableBase.__init__(self)
    self.data =3D data
    self.rowLabels =3D rowLabels
    self.colLabels =3D colLabels

def GetNumberRows(self):
    try:
        return len(self.data)
    except (TypeError):
        pass

def GetNumberCols(self):
    try:
        return len(self.data[0])
    except:
        pass

def GetColLabelValue(self, col):
    if self.colLabels:
        return self.colLabels[col]

def IsEmptyCell(self, row, col):
    return False

def GetValue(self, row, col):
    try:
        return self.data[row][col]
    except:
        pass

def SetValue(self, row, col, value):
    pass

if name =3D=3D ‘main’:
app =3D wx.PySimpleApp()
frame =3D TestFrame(None)
frame.Show(True)
app.MainLoop()


wxpython-users mailing list
wxpython-users@lists.wxwidgets.org
http://lists.wxwidgets.org/mailman/listinfo/wxpython-users

-------------- next part --------------
An HTML attachment was scrubbed…
URL: http://lists.wxwidgets.org/pipermail/wxpython-users/attachments/200808=
20/b818aa2c/attachment.htm



wxpython-users mailing list
wxpython-users@lists.wxwidgets.org
http://lists.wxwidgets.org/mailman/listinfo/wxpython-users

End of wxpython-users Digest, Vol 6, Issue 124


Hi, Ron

I believe you need to update self.data inside GenericTable.SetValue, to reflect the change coming in from the UI.

--Grant

···

On 20 Aug, 2008, at 05:36, Barak, Ron wrote:

Hi Raffaello,

Thanks for the prompt answer.

I fixed the syntax error you mentioned, so - now you can see the real problem, namely, running the script and typing 'www' and <Enter> in the top left cell, produces:

$ python ./DemoGridGeneric.py
row== 0 ;col== 0 ;old_val== Bob ;new_val== Bob ;new== WWW

But the grid still shows the original value 'Bob' on the screen.

The fixed program is below.

Bye,
Ron.

-------------------------

#!/usr/bin/env python

import wx
import wx.grid
import string

data = (("Bob", "Dernier"), ("Ryne", "Sandberg"),
        ("Gary", "Matthews"), ("Leon", "Durham"),
        ("Keith", "Moreland"), ("Ron", "Cey"),
        ("Jody", "Davis"), ("Larry", "Bowa"),
        ("Rick", "Sutcliffe"))

colLabels = ("Last", "First")
rowLabels = ("CF", "2B", "LF", "1B", "RF", "3B", "C", "SS", "P")

class SimpleGrid(wx.grid.Grid):
    def __init__(self, parent):
        wx.grid.Grid.__init__(self, parent, -1)
        tableBase = GenericTable(data, rowLabels, colLabels)
        self.SetTable(tableBase)

class TestFrame(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, parent, -1, "ForceRefresh() working ?",
                size=(275, 275))
        self.grid = SimpleGrid(self)
        self.BindTableEvents()
        self.grid.SetDefaultEditor(UpCaseCellEditor())
        self.grid.AutoSize()

    def OnGridCellChange(self, evt):
        row,col = evt.GetRow(),evt.GetCol()
        old_val = self.grid.GetTable().GetValue(row,col)
        new = self.grid.__dict__["changed_val"]
        self.grid.SetCellValue(row,col,new)
        self.grid.ForceRefresh()
        new_val = self.grid.GetTable().GetValue(row,col)
        print "row==",row,";col==",col,";old_val==",old_val,";new_val==",new_val,";new==",new

    def BindTableEvents(self):
        self.Bind(event=wx.grid.EVT_GRID_CELL_CHANGE, handler=self.OnGridCellChange, source=None)

    def SetDefaultCellEditor(self,grid):
        self.editor = grid.SetDefaultEditor(grid_editor.UpCaseCellEditor())

class UpCaseCellEditor(wx.grid.PyGridCellEditor):
    def __init__(self):
        wx.grid.PyGridCellEditor.__init__(self)

    def Create(self, parent, id, evtHandler):
        self._tc = wx.TextCtrl(parent, id, "")
        self._tc.SetInsertionPoint(0)
        self.SetControl(self._tc)

        if evtHandler:
            self._tc.PushEventHandler(evtHandler)

        self._tc.Bind(wx.EVT_CHAR, self.OnChar)

    def SetSize(self, rect):
        self._tc.SetDimensions(rect.x, rect.y, rect.width+2, rect.height+2,
                               wx.SIZE_ALLOW_MINUS_ONE)

    def BeginEdit(self, row, col, grid):
        self.startValue = grid.GetTable().GetValue(row, col)
        self._tc.SetValue(self.startValue)
        self._tc.SetInsertionPointEnd()
        self._tc.SetFocus()
        self._tc.SetSelection(0, self._tc.GetLastPosition())

    def EndEdit(self, row, col, grid):
        changed = False

        val = self._tc.GetValue()

        if val != self.startValue:
            changed = True
            grid.GetTable().SetValue(row, col, val)
            """
            The contents of 'val', could be retrieved from outside
            as: self.grid.__dict__["changed_val"]
            """
            grid.changed_val = val

        self.startValue = ''
        self._tc.SetValue('')

        return changed

    def Reset(self):
        self._tc.SetValue(self.startValue)
        self._tc.SetInsertionPointEnd()

    def Clone(self):
        return UpCaseCellEditor()

    def StartingKey(self, evt):
        self.OnChar(evt)
        if evt.GetSkipped():
            self._tc.EmulateKeyPress(evt)

    def OnChar(self, evt):
        key = evt.GetKeyCode()
        if key > 255:
            evt.Skip()
            return
        char = chr(key)
        if char in string.letters:
            char = char.upper()
            self._tc.WriteText(char)
        else:
            evt.Skip()

class GenericTable(wx.grid.PyGridTableBase):

    def __init__(self, data, rowLabels=None, colLabels=None):
        wx.grid.PyGridTableBase.__init__(self)
        self.data = data
        self.rowLabels = rowLabels
        self.colLabels = colLabels

    def GetNumberRows(self):
        try:
            return len(self.data)
        except (TypeError):
            pass
    def GetNumberCols(self):
        try:
            return len(self.data[0])
        except:
            pass

    def GetColLabelValue(self, col):
        if self.colLabels:
            return self.colLabels[col]

    def IsEmptyCell(self, row, col):
        return False
    def GetValue(self, row, col):
        try:
            return self.data[row][col]
        except:
            pass

    def SetValue(self, row, col, value):
        pass

if __name__ == '__main__':
    app = wx.PySimpleApp()
    frame = TestFrame(None)
    frame.Show(True)
    app.MainLoop()

----------------------------------------------------------------------

Message: 1
Date: Wed, 20 Aug 2008 13:10:29 +0200
From: raffaello <barbarossa.platz@gmail.com>
Subject: Re: [wxpython-users] Re: I cannot make new values show in a
        grid cell, even though ForceRefresh() is called.
To: wxpython-users@lists.wxwidgets.org
Message-ID:
        <5caf8fc00808200410u2e57552bke9f82b15fa04a8b1@mail.gmail.com>
Content-Type: text/plain; charset="iso-8859-1"

You just misplaced a line, the function should read

    def OnGridCellChange(self, evt):
        row,col =3D evt.GetRow(),evt.GetCol()
        old_val =3D self.grid.GetTable().GetValue(row,col)

        *new_val =3D self.grid.GetTable().GetValue(**row,col)*

        new =3D self.grid.__dict__["changed_val"]
        self.grid.SetCellValue(row,col,new_val)
        self.grid.ForceRefresh()

        print
"row=3D=3D",row,";col=3D=3D",col,";old_val=3D=3D",old_val,";new_val=3D=3D",=
new_val,";new=3D=3D",new

I wonder why the stdout did not tell you that. I received at once the following error message:

C:/Python25/pythonw.exe -u "C:/Python_programs/Guests/GridNotWorking.py"
Traceback (most recent call last):
  File "C:/Python_programs/Guests/GridNotWorking.py", line 37, in OnGridCellChange
    self.grid.SetCellValue(row,col,new_val)
UnboundLocalError: local variable 'new_val' referenced before assignment

So long

2008/8/20 Barak, Ron <Ron.Barak@lsi.com>

> Hi Raffaello,
>
> Sorry it took me awhile to create a demo of my post of 2008.08.17: "I
> *
> cannot* *make* *new* *values* *show* *in* *a* *grid* *cell*, *even* *
> though* *ForceRefresh*() *is* *called*." as requested.
>
> Below is the program, with the 'offending' function:
>
> def OnGridCellChange(self, evt):
> row,col =3D evt.GetRow(),evt.GetCol()
> old_val =3D self.grid.GetTable().GetValue(row,col)
> new =3D self.grid.__dict__["changed_val"]
> self.grid.SetCellValue(row,col,new_val)
> self.grid.ForceRefresh()
> new_val =3D self.grid.GetTable().GetValue(row,col)
> print
> "row=3D=3D",row,";col=3D=3D",col,";old_val=3D=3D",old_val,";new_val=3D
> =3D=
",new_val,";new=3D=3D",new
> Where the print line demonstrate that the value is changed, but the
> grid itself is not updated on the screen (in spite of
> self.grid.ForceRefresh()) .
>
> Any suggestions would be welcome.
>
> Bye,
> Ron.
>
> ------------------------------
> #!/usr/bin/env python
>
> import wx
> import wx.grid
> import string
>
> data =3D (("Bob", "Dernier"), ("Ryne", "Sandberg"),
> ("Gary", "Matthews"), ("Leon", "Durham"),
> ("Keith", "Moreland"), ("Ron", "Cey"),
> ("Jody", "Davis"), ("Larry", "Bowa"),
> ("Rick", "Sutcliffe"))
>
> colLabels =3D ("Last", "First")
> rowLabels =3D ("CF", "2B", "LF", "1B", "RF", "3B", "C", "SS", "P")
>
> class SimpleGrid(wx.grid.Grid):
> def __init__(self, parent):
> wx.grid.Grid.__init__(self, parent, -1)
> tableBase =3D GenericTable(data, rowLabels, colLabels)
> self.SetTable(tableBase)
>
> class TestFrame(wx.Frame):
> def __init__(self, parent):
> wx.Frame.__init__(self, parent, -1, "ForceRefresh() working ?",
> size=3D(275, 275))
> self.grid =3D SimpleGrid(self)
> self.BindTableEvents()
> self.grid.SetDefaultEditor(UpCaseCellEditor())
> self.grid.AutoSize()
>
> def OnGridCellChange(self, evt):
> row,col =3D evt.GetRow(),evt.GetCol()
> old_val =3D self.grid.GetTable().GetValue(row,col)
> new =3D self.grid.__dict__["changed_val"]
> self.grid.SetCellValue(row,col,new_val)
> self.grid.ForceRefresh()
> new_val =3D self.grid.GetTable().GetValue(row,col)
> print
> "row=3D=3D",row,";col=3D=3D",col,";old_val=3D=3D",old_val,";new_val=3D
> =3D=
",new_val,";new=3D=3D",new
>
> def BindTableEvents(self):
> self.Bind(event=3Dwx.grid.EVT_GRID_CELL_CHANGE,
> handler=3Dself.OnGridCellChange, source=3DNone)
>
> def SetDefaultCellEditor(self,grid):
> self.editor =3D
> grid.SetDefaultEditor(grid_editor.UpCaseCellEdito=
r())
>
> class UpCaseCellEditor(wx.grid.PyGridCellEditor):
> def __init__(self):
> wx.grid.PyGridCellEditor.__init__(self)
>
> def Create(self, parent, id, evtHandler):
> self._tc =3D wx.TextCtrl(parent, id, "")
> self._tc.SetInsertionPoint(0)
> self.SetControl(self._tc)
>
> if evtHandler:
> self._tc.PushEventHandler(evtHandler)
>
> self._tc.Bind(wx.EVT_CHAR, self.OnChar)
>
> def SetSize(self, rect):
> self._tc.SetDimensions(rect.x, rect.y, rect.width+2,
> rect.height+=
2,
> wx.SIZE_ALLOW_MINUS_ONE)
>
> def BeginEdit(self, row, col, grid):
> self.startValue =3D grid.GetTable().GetValue(row, col)
> self._tc.SetValue(self.startValue)
> self._tc.SetInsertionPointEnd()
> self._tc.SetFocus()
> self._tc.SetSelection(0, self._tc.GetLastPosition())
>
> def EndEdit(self, row, col, grid):
> changed =3D False
>
> val =3D self._tc.GetValue()
>
> if val !=3D self.startValue:
> changed =3D True
> grid.GetTable().SetValue(row, col, val)
> """
> The contents of 'val', could be retrieved from outside
> as: self.grid.__dict__["changed_val"]
> """
> grid.changed_val =3D val
>
> self.startValue =3D ''
> self._tc.SetValue('')
>
> return changed
>
> def Reset(self):
> self._tc.SetValue(self.startValue)
> self._tc.SetInsertionPointEnd()
>
> def Clone(self):
> return UpCaseCellEditor()
>
> def StartingKey(self, evt):
> self.OnChar(evt)
> if evt.GetSkipped():
> self._tc.EmulateKeyPress(evt)
>
> def OnChar(self, evt):
> key =3D evt.GetKeyCode()
> if key > 255:
> evt.Skip()
> return
> char =3D chr(key)
> if char in string.letters:
> char =3D char.upper()
> self._tc.WriteText(char)
> else:
> evt.Skip()
>
> class GenericTable(wx.grid.PyGridTableBase):
>
> def __init__(self, data, rowLabels=3DNone, colLabels=3DNone):
> wx.grid.PyGridTableBase.__init__(self)
> self.data =3D data
> self.rowLabels =3D rowLabels
> self.colLabels =3D colLabels
>
> def GetNumberRows(self):
> try:
> return len(self.data)
> except (TypeError):
> pass
>
> def GetNumberCols(self):
> try:
> return len(self.data[0])
> except:
> pass
>
> def GetColLabelValue(self, col):
> if self.colLabels:
> return self.colLabels[col]
>
> def IsEmptyCell(self, row, col):
> return False
>
> def GetValue(self, row, col):
> try:
> return self.data[row][col]
> except:
> pass
>
> def SetValue(self, row, col, value):
> pass
>
> if __name__ =3D=3D '__main__':
> app =3D wx.PySimpleApp()
> frame =3D TestFrame(None)
> frame.Show(True)
> app.MainLoop()
>
> _______________________________________________
> wxpython-users mailing list
> wxpython-users@lists.wxwidgets.org
> http://lists.wxwidgets.org/mailman/listinfo/wxpython-users
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.wxwidgets.org/pipermail/wxpython-users/attachments/200808=
20/b818aa2c/attachment.htm

------------------------------

_______________________________________________
wxpython-users mailing list
wxpython-users@lists.wxwidgets.org
http://lists.wxwidgets.org/mailman/listinfo/wxpython-users

End of wxpython-users Digest, Vol 6, Issue 124
**********************************************

_______________________________________________
wxpython-users mailing list
wxpython-users@lists.wxwidgets.org
http://lists.wxwidgets.org/mailman/listinfo/wxpython-users

Barak, Ron wrote:

Hi Raffaello,

Thanks for the prompt answer.

I fixed the syntax error you mentioned, so - now you can see the real
problem, namely, running the script and typing 'www' and <Enter> in
the top left cell, produces:

    $ python ./DemoGridGeneric.py
    row== 0 ;col== 0 ;old_val== Bob ;new_val== Bob ;new== WWW

But the grid still shows the original value 'Bob' on the screen.

Of course it does. Look at your GenericTable class, which is the table
handler for your grid:

class GenericTable(wx.grid.PyGridTableBase):
    ...
    def SetValue(self, row, col, value):
        pass

There's no way to change any of your cells. When your top-level class
calls "SetCellValue", it eventually calls your GenericTable.SetValue,
which promptly throws the data away. When you refresh the table, it
calls your GenericTable.GetValue function, which returns the old value.
You have successfully created a read-only grid.

Judicious use of "print" statements, instead of jumping to conclusions,
would have made this all clear. You need to take a step back and figure
out what all this code is supposed to do.

···

--
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.

Tim and Grant are right, the problem is in the structure of the table.
I changed the data to
data = ([“Bob”, “Dernier”], [“Ryne”, “Sandberg”],
[“Gary”, “Matthews”], [“Leon”, “Durham”],
[“Keith”, “Moreland”], [“Ron”, “Cey”],
[“Jody”, “Davis”], [“Larry”, “Bowa”],
[“Rick”, “Sutcliffe”])
(tuples cannot be changed), and added a line to the method EndEdit in the custom editor:
grid.GetTable().SetValue(row, col, val)
grid.GetTable().data[row][col] = val
and then the grid worked fine.

BTW, life is already a maze on its own, without further complications with tables. For such simple data, wx.grid.Grid is enough.

···

2008/8/20 Tim Roberts timr@probo.com

Barak, Ron wrote:

Hi Raffaello,

Thanks for the prompt answer.

I fixed the syntax error you mentioned, so - now you can see the real

problem, namely, running the script and typing ‘www’ and in

the top left cell, produces:

$ python ./DemoGridGeneric.py
row== 0 ;col== 0 ;old_val== Bob ;new_val== Bob ;new== WWW

But the grid still shows the original value ‘Bob’ on the screen.

Of course it does. Look at your GenericTable class, which is the table

handler for your grid:

class GenericTable(wx.grid.PyGridTableBase):

...

def SetValue(self, row, col, value):

    pass

There’s no way to change any of your cells. When your top-level class

calls “SetCellValue”, it eventually calls your GenericTable.SetValue,

which promptly throws the data away. When you refresh the table, it

calls your GenericTable.GetValue function, which returns the old value.

You have successfully created a read-only grid.

Judicious use of “print” statements, instead of jumping to conclusions,

would have made this all clear. You need to take a step back and figure

out what all this code is supposed to do.

Tim Roberts, timr@probo.com

Providenza & Boekelheide, Inc.


wxpython-users mailing list

wxpython-users@lists.wxwidgets.org

http://lists.wxwidgets.org/mailman/listinfo/wxpython-users

Hi Grant,

You hit the nail on the head!

There were two problems with the code I sent to demonstrate the apparent ForceRefresh() not working.

The first problem was - as you say, that the SetValue() function did nothing.
The second problem was - I was using (immutable) tuples - that are, well - immutable. :slight_smile:

Once I fixed these problems, magically - ForceRefresh() started working again :wink:

The working code is below. JICSII*.

Many thanks Grant, Tim Roberts, Raffaello, and others for your invaluable insights.
Ron.

* JICSII - just in case someone is interested

···

---------------------------------------------------------------
#!/usr/bin/env python

import wx
import wx.grid
import string

'''
data = (("Bob", "Dernier"), ("Ryne", "Sandberg"),
        ("Gary", "Matthews"), ("Leon", "Durham"),
        ("Keith", "Moreland"), ("Ron", "Cey"),
        ("Jody", "Davis"), ("Larry", "Bowa"),
        ("Rick", "Sutcliffe"))
'''
data = [["Bob", "Dernier"], ["Ryne", "Sandberg"],
        ["Gary", "Matthews"], ["Leon", "Durham"],
        ["Keith", "Moreland"], ["Ron", "Cey"],
        ["Jody", "Davis"], ["Larry", "Bowa"],
        ["Rick", "Sutcliffe"]]

colLabels = ("Last", "First")
rowLabels = ("CF", "2B", "LF", "1B", "RF", "3B", "C", "SS", "P")

class SimpleGrid(wx.grid.Grid):
    def __init__(self, parent):
        wx.grid.Grid.__init__(self, parent, -1)
        tableBase = GenericTable(data, rowLabels, colLabels)
        self.SetTable(tableBase)

class TestFrame(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, parent, -1, "ForceRefresh() working ?",
                size=(275, 275))
        self.grid = SimpleGrid(self)
        self.BindTableEvents()
        self.grid.SetDefaultEditor(UpCaseCellEditor())
        self.grid.AutoSize()

    def OnGridCellChange(self, evt):
        row,col = evt.GetRow(),evt.GetCol()
        old_val = self.grid.GetTable().GetValue(row,col)
        new = self.grid.__dict__["changed_val"]
        self.grid.SetCellValue(row,col,new)
        self.grid.ForceRefresh()
        new_val = self.grid.GetTable().GetValue(row,col)
        print "row==",row,";col==",col,";old_val==",old_val,";new_val==",new_val,";new==",new

    def BindTableEvents(self):
        self.Bind(event=wx.grid.EVT_GRID_CELL_CHANGE, handler=self.OnGridCellChange, source=None)

    def SetDefaultCellEditor(self,grid):
        self.editor = grid.SetDefaultEditor(grid_editor.UpCaseCellEditor())

class UpCaseCellEditor(wx.grid.PyGridCellEditor):
    def __init__(self):
        wx.grid.PyGridCellEditor.__init__(self)

    def Create(self, parent, id, evtHandler):
        self._tc = wx.TextCtrl(parent, id, "")
        self._tc.SetInsertionPoint(0)
        self.SetControl(self._tc)

        if evtHandler:
            self._tc.PushEventHandler(evtHandler)

        self._tc.Bind(wx.EVT_CHAR, self.OnChar)

    def SetSize(self, rect):
        self._tc.SetDimensions(rect.x, rect.y, rect.width+2, rect.height+2,
                               wx.SIZE_ALLOW_MINUS_ONE)

    def BeginEdit(self, row, col, grid):
        self.startValue = grid.GetTable().GetValue(row, col)
        self._tc.SetValue(self.startValue)
        self._tc.SetInsertionPointEnd()
        self._tc.SetFocus()
        self._tc.SetSelection(0, self._tc.GetLastPosition())

    def EndEdit(self, row, col, grid):
        changed = False

        val = self._tc.GetValue()

        if val != self.startValue:
            changed = True
            grid.GetTable().SetValue(row, col, val)
            """
            The contents of 'val', could be retrieved from outside
            as: self.grid.__dict__["changed_val"]
            """
            grid.changed_val = val

        self.startValue = ''
        self._tc.SetValue('')

        return changed

    def Reset(self):
        self._tc.SetValue(self.startValue)
        self._tc.SetInsertionPointEnd()

    def Clone(self):
        return UpCaseCellEditor()

    def StartingKey(self, evt):
        self.OnChar(evt)
        if evt.GetSkipped():
            self._tc.EmulateKeyPress(evt)

    def OnChar(self, evt):
        key = evt.GetKeyCode()
        if key > 255:
            evt.Skip()
            return
        char = chr(key)
        if char in string.letters:
            char = char.upper()
            self._tc.WriteText(char)
        else:
            evt.Skip()

class GenericTable(wx.grid.PyGridTableBase):

    def __init__(self, data, rowLabels=None, colLabels=None):
        wx.grid.PyGridTableBase.__init__(self)
        self.data = data
        self.rowLabels = rowLabels
        self.colLabels = colLabels

    def GetNumberRows(self):
        try:
            return len(self.data)
        except (TypeError):
            pass
    def GetNumberCols(self):
        try:
            return len(self.data[0])
        except:
            pass

    def GetColLabelValue(self, col):
        if self.colLabels:
            return self.colLabels[col]

    def IsEmptyCell(self, row, col):
        return False
    def GetValue(self, row, col):
        try:
            return self.data[row][col]
        except:
            pass

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

if __name__ == '__main__':
    app = wx.PySimpleApp()
    frame = TestFrame(None)
    frame.Show(True)
    app.MainLoop()

-----Original Message-----
From: Grant Baillie [mailto:grant@osafoundation.org]
Sent: Wednesday, 20 August, 2008 18:18
To: wxpython-users@lists.wxwidgets.org
Subject: Re: [wxpython-users] Re: I cannot make new values show in a grid cell, even though ForceRefresh() is called.

Hi, Ron

I believe you need to update self.data inside GenericTable.SetValue, to reflect the change coming in from the UI.

--Grant

On 20 Aug, 2008, at 05:36, Barak, Ron wrote:

Hi Raffaello,

Thanks for the prompt answer.

I fixed the syntax error you mentioned, so - now you can see the real
problem, namely, running the script and typing 'www' and <Enter> in
the top left cell, produces:

$ python ./DemoGridGeneric.py
row== 0 ;col== 0 ;old_val== Bob ;new_val== Bob ;new== WWW

But the grid still shows the original value 'Bob' on the screen.

The fixed program is below.

Bye,
Ron.

-------------------------

#!/usr/bin/env python

import wx
import wx.grid
import string

data = (("Bob", "Dernier"), ("Ryne", "Sandberg"),
        ("Gary", "Matthews"), ("Leon", "Durham"),
        ("Keith", "Moreland"), ("Ron", "Cey"),
        ("Jody", "Davis"), ("Larry", "Bowa"),
        ("Rick", "Sutcliffe"))

colLabels = ("Last", "First")
rowLabels = ("CF", "2B", "LF", "1B", "RF", "3B", "C", "SS", "P")

class SimpleGrid(wx.grid.Grid):
    def __init__(self, parent):
        wx.grid.Grid.__init__(self, parent, -1)
        tableBase = GenericTable(data, rowLabels, colLabels)
        self.SetTable(tableBase)

class TestFrame(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, parent, -1, "ForceRefresh() working
?",
                size=(275, 275))
        self.grid = SimpleGrid(self)
        self.BindTableEvents()
        self.grid.SetDefaultEditor(UpCaseCellEditor())
        self.grid.AutoSize()

    def OnGridCellChange(self, evt):
        row,col = evt.GetRow(),evt.GetCol()
        old_val = self.grid.GetTable().GetValue(row,col)
        new = self.grid.__dict__["changed_val"]
        self.grid.SetCellValue(row,col,new)
        self.grid.ForceRefresh()
        new_val = self.grid.GetTable().GetValue(row,col)
        print
"row

=
",row
,";col==",col,";old_val==",old_val,";new_val==",new_val,";new==",new

    def BindTableEvents(self):
        self.Bind(event=wx.grid.EVT_GRID_CELL_CHANGE,
handler=self.OnGridCellChange, source=None)

    def SetDefaultCellEditor(self,grid):
        self.editor =
grid.SetDefaultEditor(grid_editor.UpCaseCellEditor())

class UpCaseCellEditor(wx.grid.PyGridCellEditor):
    def __init__(self):
        wx.grid.PyGridCellEditor.__init__(self)

    def Create(self, parent, id, evtHandler):
        self._tc = wx.TextCtrl(parent, id, "")
        self._tc.SetInsertionPoint(0)
        self.SetControl(self._tc)

        if evtHandler:
            self._tc.PushEventHandler(evtHandler)

        self._tc.Bind(wx.EVT_CHAR, self.OnChar)

    def SetSize(self, rect):
        self._tc.SetDimensions(rect.x, rect.y, rect.width+2,
rect.height+2,
                               wx.SIZE_ALLOW_MINUS_ONE)

    def BeginEdit(self, row, col, grid):
        self.startValue = grid.GetTable().GetValue(row, col)
        self._tc.SetValue(self.startValue)
        self._tc.SetInsertionPointEnd()
        self._tc.SetFocus()
        self._tc.SetSelection(0, self._tc.GetLastPosition())

    def EndEdit(self, row, col, grid):
        changed = False

        val = self._tc.GetValue()

        if val != self.startValue:
            changed = True
            grid.GetTable().SetValue(row, col, val)
            """
            The contents of 'val', could be retrieved from outside
            as: self.grid.__dict__["changed_val"]
            """
            grid.changed_val = val

        self.startValue = ''
        self._tc.SetValue('')

        return changed

    def Reset(self):
        self._tc.SetValue(self.startValue)
        self._tc.SetInsertionPointEnd()

    def Clone(self):
        return UpCaseCellEditor()

    def StartingKey(self, evt):
        self.OnChar(evt)
        if evt.GetSkipped():
            self._tc.EmulateKeyPress(evt)

    def OnChar(self, evt):
        key = evt.GetKeyCode()
        if key > 255:
            evt.Skip()
            return
        char = chr(key)
        if char in string.letters:
            char = char.upper()
            self._tc.WriteText(char)
        else:
            evt.Skip()

class GenericTable(wx.grid.PyGridTableBase):

    def __init__(self, data, rowLabels=None, colLabels=None):
        wx.grid.PyGridTableBase.__init__(self)
        self.data = data
        self.rowLabels = rowLabels
        self.colLabels = colLabels

    def GetNumberRows(self):
        try:
            return len(self.data)
        except (TypeError):
            pass
    def GetNumberCols(self):
        try:
            return len(self.data[0])
        except:
            pass

    def GetColLabelValue(self, col):
        if self.colLabels:
            return self.colLabels[col]

    def IsEmptyCell(self, row, col):
        return False
    def GetValue(self, row, col):
        try:
            return self.data[row][col]
        except:
            pass

    def SetValue(self, row, col, value):
        pass

if __name__ == '__main__':
    app = wx.PySimpleApp()
    frame = TestFrame(None)
    frame.Show(True)
    app.MainLoop()

----------------------------------------------------------------------

Message: 1
Date: Wed, 20 Aug 2008 13:10:29 +0200
From: raffaello <barbarossa.platz@gmail.com>
Subject: Re: [wxpython-users] Re: I cannot make new values show in a
        grid cell, even though ForceRefresh() is called.
To: wxpython-users@lists.wxwidgets.org
Message-ID:
        <5caf8fc00808200410u2e57552bke9f82b15fa04a8b1@mail.gmail.com>
Content-Type: text/plain; charset="iso-8859-1"

You just misplaced a line, the function should read

    def OnGridCellChange(self, evt):
        row,col =3D evt.GetRow(),evt.GetCol()
        old_val =3D self.grid.GetTable().GetValue(row,col)

        *new_val =3D self.grid.GetTable().GetValue(**row,col)*

        new =3D self.grid.__dict__["changed_val"]
        self.grid.SetCellValue(row,col,new_val)
        self.grid.ForceRefresh()

        print
"row

3D
=3D",row,";col=3D=3D",col,";old_val=3D=3D",old_val,";new_val=3D=3D",=
new_val,";new=3D=3D",new

I wonder why the stdout did not tell you that. I received at once the
following error message:

C:/Python25/pythonw.exe -u "C:/Python_programs/Guests/
GridNotWorking.py"
Traceback (most recent call last):
  File "C:/Python_programs/Guests/GridNotWorking.py", line 37, in
OnGridCellChange
    self.grid.SetCellValue(row,col,new_val)
UnboundLocalError: local variable 'new_val' referenced before
assignment

So long

2008/8/20 Barak, Ron <Ron.Barak@lsi.com>

> Hi Raffaello,
>
> Sorry it took me awhile to create a demo of my post of 2008.08.17:
"I
> *
> cannot* *make* *new* *values* *show* *in* *a* *grid* *cell*,
*even* *
> though* *ForceRefresh*() *is* *called*." as requested.
>
> Below is the program, with the 'offending' function:
>
> def OnGridCellChange(self, evt):
> row,col =3D evt.GetRow(),evt.GetCol()
> old_val =3D self.grid.GetTable().GetValue(row,col)
> new =3D self.grid.__dict__["changed_val"]
> self.grid.SetCellValue(row,col,new_val)
> self.grid.ForceRefresh()
> new_val =3D self.grid.GetTable().GetValue(row,col)
> print
>
"row=3D=3D",row,";col=3D=3D",col,";old_val=3D=3D",old_val,";new_val=3D
> =3D=
",new_val,";new=3D=3D",new
> Where the print line demonstrate that the value is changed, but the
> grid itself is not updated on the screen (in spite of
> self.grid.ForceRefresh()) .
>
> Any suggestions would be welcome.
>
> Bye,
> Ron.
>
> ------------------------------
> #!/usr/bin/env python
>
> import wx
> import wx.grid
> import string
>
> data =3D (("Bob", "Dernier"), ("Ryne", "Sandberg"),
> ("Gary", "Matthews"), ("Leon", "Durham"),
> ("Keith", "Moreland"), ("Ron", "Cey"),
> ("Jody", "Davis"), ("Larry", "Bowa"),
> ("Rick", "Sutcliffe"))
>
> colLabels =3D ("Last", "First")
> rowLabels =3D ("CF", "2B", "LF", "1B", "RF", "3B", "C", "SS", "P")
>
> class SimpleGrid(wx.grid.Grid):
> def __init__(self, parent):
> wx.grid.Grid.__init__(self, parent, -1)
> tableBase =3D GenericTable(data, rowLabels, colLabels)
> self.SetTable(tableBase)
>
> class TestFrame(wx.Frame):
> def __init__(self, parent):
> wx.Frame.__init__(self, parent, -1, "ForceRefresh()
working ?",
> size=3D(275, 275))
> self.grid =3D SimpleGrid(self)
> self.BindTableEvents()
> self.grid.SetDefaultEditor(UpCaseCellEditor())
> self.grid.AutoSize()
>
> def OnGridCellChange(self, evt):
> row,col =3D evt.GetRow(),evt.GetCol()
> old_val =3D self.grid.GetTable().GetValue(row,col)
> new =3D self.grid.__dict__["changed_val"]
> self.grid.SetCellValue(row,col,new_val)
> self.grid.ForceRefresh()
> new_val =3D self.grid.GetTable().GetValue(row,col)
> print
>
"row=3D=3D",row,";col=3D=3D",col,";old_val=3D=3D",old_val,";new_val=3D
> =3D=
",new_val,";new=3D=3D",new
>
> def BindTableEvents(self):
> self.Bind(event=3Dwx.grid.EVT_GRID_CELL_CHANGE,
> handler=3Dself.OnGridCellChange, source=3DNone)
>
> def SetDefaultCellEditor(self,grid):
> self.editor =3D
> grid.SetDefaultEditor(grid_editor.UpCaseCellEdito=
r())
>
> class UpCaseCellEditor(wx.grid.PyGridCellEditor):
> def __init__(self):
> wx.grid.PyGridCellEditor.__init__(self)
>
> def Create(self, parent, id, evtHandler):
> self._tc =3D wx.TextCtrl(parent, id, "")
> self._tc.SetInsertionPoint(0)
> self.SetControl(self._tc)
>
> if evtHandler:
> self._tc.PushEventHandler(evtHandler)
>
> self._tc.Bind(wx.EVT_CHAR, self.OnChar)
>
> def SetSize(self, rect):
> self._tc.SetDimensions(rect.x, rect.y, rect.width+2,
> rect.height+=
2,
> wx.SIZE_ALLOW_MINUS_ONE)
>
> def BeginEdit(self, row, col, grid):
> self.startValue =3D grid.GetTable().GetValue(row, col)
> self._tc.SetValue(self.startValue)
> self._tc.SetInsertionPointEnd()
> self._tc.SetFocus()
> self._tc.SetSelection(0, self._tc.GetLastPosition())
>
> def EndEdit(self, row, col, grid):
> changed =3D False
>
> val =3D self._tc.GetValue()
>
> if val !=3D self.startValue:
> changed =3D True
> grid.GetTable().SetValue(row, col, val)
> """
> The contents of 'val', could be retrieved from outside
> as: self.grid.__dict__["changed_val"]
> """
> grid.changed_val =3D val
>
> self.startValue =3D ''
> self._tc.SetValue('')
>
> return changed
>
> def Reset(self):
> self._tc.SetValue(self.startValue)
> self._tc.SetInsertionPointEnd()
>
> def Clone(self):
> return UpCaseCellEditor()
>
> def StartingKey(self, evt):
> self.OnChar(evt)
> if evt.GetSkipped():
> self._tc.EmulateKeyPress(evt)
>
> def OnChar(self, evt):
> key =3D evt.GetKeyCode()
> if key > 255:
> evt.Skip()
> return
> char =3D chr(key)
> if char in string.letters:
> char =3D char.upper()
> self._tc.WriteText(char)
> else:
> evt.Skip()
>
> class GenericTable(wx.grid.PyGridTableBase):
>
> def __init__(self, data, rowLabels=3DNone, colLabels=3DNone):
> wx.grid.PyGridTableBase.__init__(self)
> self.data =3D data
> self.rowLabels =3D rowLabels
> self.colLabels =3D colLabels
>
> def GetNumberRows(self):
> try:
> return len(self.data)
> except (TypeError):
> pass
>
> def GetNumberCols(self):
> try:
> return len(self.data[0])
> except:
> pass
>
> def GetColLabelValue(self, col):
> if self.colLabels:
> return self.colLabels[col]
>
> def IsEmptyCell(self, row, col):
> return False
>
> def GetValue(self, row, col):
> try:
> return self.data[row][col]
> except:
> pass
>
> def SetValue(self, row, col, value):
> pass
>
> if __name__ =3D=3D '__main__':
> app =3D wx.PySimpleApp()
> frame =3D TestFrame(None)
> frame.Show(True)
> app.MainLoop()
>
>
>
> _______________________________________________
> wxpython-users mailing list
> wxpython-users@lists.wxwidgets.org
> http://lists.wxwidgets.org/mailman/listinfo/wxpython-users
>
>
-------------- next part -------------- An HTML attachment was
scrubbed...
URL:
http://lists.wxwidgets.org/pipermail/wxpython-users/attachments/200808

20/b818aa2c/attachment.htm

------------------------------

_______________________________________________
wxpython-users mailing list
wxpython-users@lists.wxwidgets.org
http://lists.wxwidgets.org/mailman/listinfo/wxpython-users

End of wxpython-users Digest, Vol 6, Issue 124
**********************************************

_______________________________________________
wxpython-users mailing list
wxpython-users@lists.wxwidgets.org
http://lists.wxwidgets.org/mailman/listinfo/wxpython-users