Search code examples
pythonwxpythonwxwidgetsdocking

wxPython: Trying to make a docking window, binding parent EVT_ACTIVATE prevents parent resizing


I'm trying to make a simple docking frame that will dock to a parent window and follow it around. So far I have the following:

class DockingFrame(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, parent, style=wx.CAPTION)

        parent.Bind(wx.EVT_MOVE, self.OnParentMove)
        parent.Bind(wx.EVT_ACTIVATE, self.OnParentActivate)
        parent.Bind(wx.EVT_SHOW, self.OnParentShow)

    def OnParentMove(self, moveEvent):
        print "Docked frame parent moved"
        pr = positioning.position(
            self.Rect,
            my='right_top', at='left_top', of=self.Parent.Rect)
        self.Move(pr.top_left)
        moveEvent.Skip()

    def OnParentActivate(self, event):
        print "Docked frame parent activated"
        self.Raise()
        event.Skip()

    def OnParentShow(self, event):
        print "Docked frame parent showed"
        self.Show(event.GetShow())
        event.Skip()

class MainFrame(wx.Frame):
    def __init__(self, title):
        wx.Frame.__init__(self, None, title=title)

        self.info_frame = DockingFrame(self)

        self.Show(True)

This works in that if I move the parent window, the docked window moves with it, and if I click on the parent window, the docked window raises itself. However, it severely interferes with the parent window's functionality. I can't close or re-size the parent window anymore, and I get tons of "Docked frame parent activated" messages whenever I click the parent. It seems I don't understand some fundamental wxPython concept, here. What is going on and how do I fix it?

I've seen that aui seems to support docking, but documentation has been sparse so I haven't attempted it. If someone could supply a minimal working code sample as to how to make a Frame dock to another Frame with aui, I could also take that approach.

Note that I'm also using pygame and twisted in this app, which may or may not be interfering here...


Solution

  • And, of course, the simple approach is to simply use the wx.FRAME_FLOAT_ON_PARENT style...

    class DockingFrame(wx.Frame):
        def __init__(self, parent):
            wx.Frame.__init__(self, parent, title="Last Hand",
                              style=wx.CAPTION  | wx.FRAME_FLOAT_ON_PARENT)
    
            parent.Bind(wx.EVT_MOVE, self.OnParentMove)
            parent.Bind(wx.EVT_SHOW, self.OnParentShow)
    
        def SnapToParent(self):
            print "*Snapping to parent"
            pr = positioning.position(
                self.Rect,
                my='right_top', at='left_top', of=self.Parent.Rect)
            self.Move(pr.top_left)
    
        def OnParentMove(self, moveEvent):
            moveEvent.Skip()
            self.SnapToParent()
    
        def OnParentShow(self, event):
            event.Skip()
            print "Parent %s" % ("Hide", "Show")[event.GetShow()]
            self.Show(event.GetShow())