Another basic what-am-I-missing-here question

I have a frame. That frame has a panel. The panel has sub panels and
sub windows that I want to be sources for drag and drop operations.

When I Bind wx.EVT_LEFT_DOWN to the sub panel or sub window, the event
is never fired.

I think I've seen documentation on this before, but for the life of me
I can't find it.

As a test, I bound EVT_LEFT_DOWN to the panel and the event fired as
long as the mouse wasn't over any of the children.

What am I missing here?

···

--
Josh English
Joshua.R.English@gmail.com
http://joshenglish.livejournal.com

Josh,

I have a frame. That frame has a panel. The panel has sub panels and
sub windows that I want to be sources for drag and drop operations.

When I Bind wx.EVT_LEFT_DOWN to the sub panel or sub window, the event
is never fired.

I think I've seen documentation on this before, but for the life of me
I can't find it.

As a test, I bound EVT_LEFT_DOWN to the panel and the event fired as
long as the mouse wasn't over any of the children.

What am I missing here?

How are you binding the event? My guess is that you are doing a self.Bind instead of subpanel.Bind...at least, that's what it sounds like from your description. See the wiki for more info: http://wiki.wxpython.org/self.Bind vs. self.button.Bind

···

-------------------
Mike Driscoll

Blog: http://blog.pythonlibrary.org
Python Extension Building Network: http://www.pythonlibrary.org

__________ Information from ESET NOD32 Antivirus, version of virus signature database 4063 (20090508) __________

The message was checked by ESET NOD32 Antivirus.

http://www.eset.com

The Code:

class SimplePanel (wx.Panel):
deimport wx

class TestWindow(wx.Window):
    def __init__(self, parent, col):
        wx.Window.__init__(self, parent, size=(48, 48), style=wx.BORDER_SIMPLE)
        self.SetBackgroundColour(col)
        self.Image=None

class PieceServer(wx.Panel):
    def __init__(self, parent, name, imgFile):
        wx.Panel.__init__(self, parent, size=(48,48), style=wx.BORDER_SIMPLE)
        self.SetName(name)
        self.SetBackgroundColour("white")
        self.Bitmap = wx.Bitmap(imgFile, wx.BITMAP_TYPE_PNG)
        wx.StaticBitmap(self, bitmap=self.Bitmap, pos=(4,4))

        #~ Start drag and drop

        self.Bind(wx.EVT_LEFT_DOWN, self.OnDrag)

    def OnDrag(self, event):
        print event
        event.Skip()

class TestFrame(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, parent, title="Drag and Drop Test")
        panel = wx.Panel(self)
        sizer = wx.BoxSizer(wx.HORIZONTAL)
        self.One = TestWindow(panel, "white")
        self.Two = TestWindow(panel, "gray50")
        self.BlackPawnServer = PieceServer(panel, "bpawn", "bpawn.png")
        sizer.Add(self.BlackPawnServer, 0, wx.ALL, 10)
        sizer.Add(self.One, 0, wx.ALL, 10)
        sizer.Add(self.Two, 0, wx.ALL, 10)
        panel.SetSizer(sizer)
        self.Layout()

        panel.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)

    def OnLeftDown(self, event):
        print event
        print event.Position

from wx.lib.mixins.inspection import InspectionMixin
class App(wx.App, InspectionMixin):
    def OnInit(self):
        self.Init()

        frame = TestFrame(None)
        self.SetTopWindow(frame)
        frame.Show(True)
        return True

app = App(0)
app.MainLoop()
app.Destroy()

/---
In the Frame, if I bind EVT_LEFT_DOWN to the panel, the OnLeftDown
method only triggers at the Frame level, but not when any of the sub
windows work.

I did re-read the page at PushEventHandler - wxPyWiki
and that could solve my problem. It's strange to me that I have to
bind mouse clicks at th eframe level, or push the event handler up.
I'm sure there's a good reason for that, but it's beyond my ken.

Josh

bpawn.png

···

On 5/9/09, Mike Driscoll <mike@pythonlibrary.org> wrote:

Josh,

> I have a frame. That frame has a panel. The panel has sub panels and
> sub windows that I want to be sources for drag and drop operations.
>
> When I Bind wx.EVT_LEFT_DOWN to the sub panel or sub window, the event
> is never fired.
>
> I think I've seen documentation on this before, but for the life of me
> I can't find it.
>
> As a test, I bound EVT_LEFT_DOWN to the panel and the event fired as
> long as the mouse wasn't over any of the children.
>
> What am I missing here?
>
>
>

How are you binding the event? My guess is that you are doing a self.Bind
instead of subpanel.Bind...at least, that's what it sounds like from your
description. See the wiki for more info:
http://wiki.wxpython.org/self.Bind vs. self.button.Bind

-------------------
Mike Driscoll

Blog: http://blog.pythonlibrary.org
Python Extension Building Network: http://www.pythonlibrary.org

__________ Information from ESET NOD32 Antivirus, version of virus
signature database 4063 (20090508) __________

The message was checked by ESET NOD32 Antivirus.

http://www.eset.com

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

--
Josh English
Joshua.R.English@gmail.com

Mike Driscoll wrote:

How are you binding the event? My guess is that you are doing a self.Bind instead of subpanel.Bind...at least, that's what it sounds like from your description. See the wiki for more info: http://wiki.wxpython.org/self.Bind vs. self.button.Bind

The unbroken link is: self.Bind vs. self.button.Bind - wxPyWiki

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!

Josh English wrote:

I did re-read the page at PushEventHandler - wxPyWiki
and that could solve my problem. It's strange to me that I have to
bind mouse clicks at th eframe level, or push the event handler up.
I'm sure there's a good reason for that, but it's beyond my ken.

Mouse events are not command events, and non-command events are only sent to the widget where the event happened. In other words the mouse events that happen within the bounds of widget Foo are only sent to Foo, not Foo's parent, grandparent, etc. so the events must be caught by Foo.

However since this is Python and since Python is full of magic, the above statement does not imply a bunch of complexity or brick walls like it would in C++. For example. just because Foo is catching the event does not mean that Foo has to be the one that processes the event. It sounds to my like you want the frame to be the one that processes the mouse events that happen in child panels. That can be done by writing the Bind like this:

  self.aSubPanel.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)

The first part of the statement tells the subpanel to make an event binding for left-down (so any left down events that are sent to it will match) but it is redirecting the processing of the event to self.OnLeftDown, where self is assumed to be the frame in your example.

See self.Bind vs. self.button.Bind - wxPyWiki

However you may want to take a closer look at your design. It may make more sense to make your Panels be their own classes and have them process the events, and let the frame be just a simple container.

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!

Robin Dunn wrote:

Mike Driscoll wrote:

How are you binding the event? My guess is that you are doing a self.Bind instead of subpanel.Bind...at least, that's what it sounds like from your description. See the wiki for more info: http://wiki.wxpython.org/self.Bind vs. self.button.Bind

The unbroken link is: self.Bind vs. self.button.Bind - wxPyWiki

Oops...stupid gmail mangled my link. Thunderbird wins again.

Mike

__________ Information from ESET NOD32 Antivirus, version of virus signature database 4063 (20090508) __________

The message was checked by ESET NOD32 Antivirus.

http://www.eset.com