PyColourChooser as GridCellEditor

hi all, in the following code I'm trying to use a pycolourchooser as a
gridcelleditor without success. At the end of the script there are two
"main" functions if you want to try the ColourComboPopup in a grid or
in a frame. In a frame it seems to work but in the grid I face these
problems (python2.5, winVista, wxpython2.8.10.1):
- no popup shown
- can't close the frame without killing the interpreter

Where am I going wrong?

Marco

···

####################
import wx
import wx.grid
import wx.combo
import wx.lib.colourchooser as cc

class ColourComboPopup(wx.combo.ComboPopup):
    # overridden ComboPopup methods
    def Init(self):
        self.value = None
        self.curitem = None

    def Create(self, parent):
        self.ccol = cc.PyColourChooser(parent, -1)
        self.ccol.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)

    def GetControl(self):
        return self.ccol

    def GetStringValue(self):
        if self.value:
            return self.ccol.GetValue(self.value)
#self.ccol.GetItemText(self.value)
        return ""

    def OnPopup(self):
        if self.value:
            self.ccol.EnsureVisible(self.value)

    def GetAdjustedSize(self, minWidth, prefHeight, maxHeight):
        return wx.Size(430,300) #wx.Size(minWidth+200, min(200,
maxHeight))

    def OnLeftDown(self, evt):
        # do the combobox selection
        item, flags = self.ccol.HitTest(evt.GetPosition())
        print self.ccol.GetValue()
        evt.Skip()

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

    def Create(self, parent, id, evtHandler):
        """
        Called to create the control, which must derive from
wxControl.
        """
        print 'create'
        self._tc = wx.combo.ComboCtrl(parent, id, size=(450,400))
        coldisp = ColourComboPopup()
        self._tc.SetPopupControl(coldisp)
        self.SetControl(self._tc)
        if evtHandler:
            self._tc.PushEventHandler(evtHandler)

    def SetSize(self, rect):
        """
        Called to position/size the edit control within the cell
rectangle.
        If you don't fill the cell (the rect) then be sure to override
        PaintBackground and do something meaningful there.
        """
        print 'setsize'
        self._tc.SetDimensions(rect.x, rect.y, rect.width+4,
rect.height+4,
                               wx.SIZE_ALLOW_MINUS_ONE)

    def BeginEdit(self, row, col, grid):
        """
        Fetch the value from the table and prepare the edit control
        to begin editing. Set the focus to the edit control.
        """
        print 'beginedit'
        self.startValue = grid.GetTable().GetValue(row, col)
## r,g,b,a = [int(x) for x in self.startValue.split(',')]
        self._tc.SetValue('ORANGE')
        self._tc.SetFocus()

    def EndEdit(self, row, col, grid):
        """
        Complete the editing of the current cell. Returns true if the
value
        has changed. If necessary, the control may be destroyed.
        """
        print 'endedit'
        changed = False

        pclDescr = self._tc.GetValue() #StringSelection()
        # extract pcl
        pcl = pclDescr.split(' ')[0]
        if pcl != self.startValue :
            changed = True
            grid.GetTable().SetValue(row, col, pcl) # update the table

        self.startValue = ''
        return changed

    def Reset(self):
        """
        Reset the value in the control back to its starting value.
        """
        print 'reset'
        self._tc.SetValue(self.startValue)

    def Clone(self):
        """
        Create a new object which is the copy of this one
        """
        print 'clone'
        return ColourCellEditor()

##class ColourRenderer(wx.grid.PyGridCellRenderer):
## def __init__(self):
## wx.grid.PyGridCellRenderer.__init__(self)
##
## def Draw(self, grid, attr, dc, rect, row, col, isSelected):
## val = grid.GetCellValue(row, col)
## red,green,blue, alpha = [int(x) for x in val.split(',')]
## dc.SetBackgroundMode(wx.SOLID)
## dc.SetBrush(wx.Brush(wx.Colour(red,green,blue,alpha),
wx.SOLID))
## dc.SetPen(wx.TRANSPARENT_PEN)
## dc.DrawRectangleRect(rect)
##
## dc.SetBackgroundMode(wx.TRANSPARENT)
## dc.SetFont(attr.GetFont())
##
## def Clone(self):
## return ColourRenderer()

def main1():
    import wx.grid
    class TestFrame(wx.Frame):
        def __init__(self):
            wx.Frame.__init__(self, None, title="Grid Editor",
                              size=(640,480))

            grid = wx.grid.Grid(self)
            grid.CreateGrid(50,50)
## grid.SetDefaultEditor(DatePickerCellEditor())
            grid.SetDefaultEditor(ColourCellEditor())

    app = wx.PySimpleApp()
    frame = TestFrame()
    frame.Show()
    app.MainLoop()

def main2():
    """Simple test display."""
    class App(wx.App):
        def OnInit(self):
            frame = wx.Frame(None, -1, 'PyColourChooser Test')

            # Added here because that's where it's supposed to be,
            # not embedded in the library. If it's embedded in the
            # library, debug messages will be generated for duplicate
            # handlers.
            wx.InitAllImageHandlers()

            chooser = wx.combo.ComboCtrl(frame, -1, size=(250,-1))
            coldisp = ColourComboPopup()
            chooser.SetPopupControl(coldisp)
            sizer = wx.BoxSizer(wx.VERTICAL)
            sizer.Add(chooser, 0, 0)
            frame.SetAutoLayout(True)
            frame.SetSizer(sizer)
            sizer.Fit(frame)

            frame.Show(True)
            self.SetTopWindow(frame)
            return True
    app = App(False)
    app.MainLoop()

if __name__ == '__main__':
    main1()

Marco Prosperi wrote:

hi all, in the following code I'm trying to use a pycolourchooser as a
gridcelleditor without success. At the end of the script there are two
"main" functions if you want to try the ColourComboPopup in a grid or
in a frame. In a frame it seems to work but in the grid I face these
problems (python2.5, winVista, wxpython2.8.10.1):
- no popup shown
- can't close the frame without killing the interpreter

Where am I going wrong?

My guess is that this is due to the ComboCtrl being a composite control. One of the triggers that causes the grid cell editors to dismiss themselves is if they loose the focus. For a composite control the first thing it usually does when it gets the focus is to redirect it to the first child component, which will send a loose focus event for itself.

···

--
Robin Dunn
Software Craftsman

My guess is that this is due to the ComboCtrl being a composite control.
One of the triggers that causes the grid cell editors to dismiss
themselves is if they loose the focus. For a composite control the
first thing it usually does when it gets the focus is to redirect it to
the first child component, which will send a loose focus event for itself.

--
Robin Dunn
Software Craftsmanhttp://wxPython.org

To circumvent the behaviour you describe I've tried the other approach
with ComboCtrl: the one with multiple inheritance, as in the first
example of the demo script. In this case, having to use two-step
creation, I can't find an easy way to create PyColourChooser in two
phases

Marco Prosperi wrote:

My guess is that this is due to the ComboCtrl being a composite control.
  One of the triggers that causes the grid cell editors to dismiss
themselves is if they loose the focus. For a composite control the
first thing it usually does when it gets the focus is to redirect it to
the first child component, which will send a loose focus event for itself.

--
Robin Dunn
Software Craftsmanhttp://wxPython.org

To circumvent the behaviour you describe I've tried the other approach
with ComboCtrl: the one with multiple inheritance, as in the first
example of the demo script. In this case, having to use two-step
creation, I can't find an easy way to create PyColourChooser in two
phases

Unless I'm missing something that is not going to make any difference. The problem is with the ComboCtrl itself, not its popup. Take a look at a ComboCtrl in the WIT, you'll see that the ComboCtrl has two child windows, a wx.TextCtrl and the popup window. When the ComboCtrl gets the focus it calls the SetFocus of the textCtrl which causes the ComboCtrl to get a kill focus event which tells the grid to hide the cell editor.

To work around this you'll need to do some tinkering of some sort with the focus events. Something like catch the combo's kill focus event so the grid doesn't see it, unless the combo popup has just been dismissed, or something like that. To be sure you get the event first you'll probably have to push another wx.EvtHandler on the stack after the one that the grid gives you.

···

--
Robin Dunn
Software Craftsman

Hi,

gestgrid_select.py (22.7 KB)

···

2009/8/4 Robin Dunn robin@alldunn.com

Marco Prosperi wrote:

My guess is that this is due to the ComboCtrl being a composite control.

One of the triggers that causes the grid cell editors to dismiss

themselves is if they loose the focus. For a composite control the

first thing it usually does when it gets the focus is to redirect it to

the first child component, which will send a loose focus event for itself.

Robin Dunn

Software Craftsmanhttp://wxPython.org

To circumvent the behaviour you describe I’ve tried the other approach

with ComboCtrl: the one with multiple inheritance, as in the first

example of the demo script. In this case, having to use two-step

creation, I can’t find an easy way to create PyColourChooser in two

phases

Unless I’m missing something that is not going to make any difference.

The problem is with the ComboCtrl itself, not its popup. Take a look at

a ComboCtrl in the WIT, you’ll see that the ComboCtrl has two child

windows, a wx.TextCtrl and the popup window. When the ComboCtrl gets

the focus it calls the SetFocus of the textCtrl which causes the

ComboCtrl to get a kill focus event which tells the grid to hide the

cell editor.

To work around this you’ll need to do some tinkering of some sort with

the focus events. Something like catch the combo’s kill focus event so

the grid doesn’t see it, unless the combo popup has just been dismissed,

or something like that. To be sure you get the event first you’ll

probably have to push another wx.EvtHandler on the stack after the one

that the grid gives you.

Robin Dunn

Software Craftsman

http://wxPython.org

–~–~---------~–~----~------------~-------~–~----~

To unsubscribe, send email to wxPython-users+unsubscribe@googlegroups.com

or visit http://groups.google.com/group/wxPython-users?hl=en

-~----------~----~----~----~------~----~------~–~—

Now go, but I noticed that when there is the selection of row the text appears black instead of white. Then when I select before the row 1 and after line 2 disappears cell value (1.1).

Did I do something wrong?
RE-attached script.

Fabio Spadaro
www.fabiospadaro.com

HI,

···

2010/8/18 Fabio Spadaro fabiolinospad@gmail.com

Hi,

2009/8/4 Robin Dunn robin@alldunn.com

Marco Prosperi wrote:

My guess is that this is due to the ComboCtrl being a composite control.

One of the triggers that causes the grid cell editors to dismiss

themselves is if they loose the focus. For a composite control the

first thing it usually does when it gets the focus is to redirect it to

the first child component, which will send a loose focus event for itself.

Robin Dunn

Software Craftsmanhttp://wxPython.org

To circumvent the behaviour you describe I’ve tried the other approach

with ComboCtrl: the one with multiple inheritance, as in the first

example of the demo script. In this case, having to use two-step

creation, I can’t find an easy way to create PyColourChooser in two

phases

Unless I’m missing something that is not going to make any difference.

The problem is with the ComboCtrl itself, not its popup. Take a look at

a ComboCtrl in the WIT, you’ll see that the ComboCtrl has two child

windows, a wx.TextCtrl and the popup window. When the ComboCtrl gets

the focus it calls the SetFocus of the textCtrl which causes the

ComboCtrl to get a kill focus event which tells the grid to hide the

cell editor.

To work around this you’ll need to do some tinkering of some sort with

the focus events. Something like catch the combo’s kill focus event so

the grid doesn’t see it, unless the combo popup has just been dismissed,

or something like that. To be sure you get the event first you’ll

probably have to push another wx.EvtHandler on the stack after the one

that the grid gives you.

Robin Dunn

Software Craftsman

http://wxPython.org

–~–~---------~–~----~------------~-------~–~----~

To unsubscribe, send email to wxPython-users+unsubscribe@googlegroups.com

or visit http://groups.google.com/group/wxPython-users?hl=en

-~----------~----~----~----~------~----~------~–~—

Now go, but I noticed that when there is the selection of row the text appears black instead of white. Then when I select before the row 1 and after line 2 disappears cell value (1.1).

Did I do something wrong?
RE-attached script.


Fabio Spadaro
www.fabiospadaro.com

Sorry. :slight_smile:


Fabio Spadaro
www.fabiospadaro.com