Unable to get screen position of windows after calling "Reparent"

I haven't used wxPython in a good while, and I'm afraid that I'm a little rusty. I'm trying to get a program working using dynamically and arbitrarily nested wxSplitterWindows. For this, the Reparent() method is essential. Unfortunately, it seems that I'm unable to get accurate screen coordinates of windows that have been re-parented. I fully concede that I'm probably doing something wrong, but I can't figure out what it is. If someone could steer me in the right direction, I would be quite grateful.

I've cooked up a minimal example. If you run the example from the terminal, and then select File->Test 1, the screen rectangle of the two little windows will be correctly printed to standard output. But then if you select File->Test 2, both of the little windows will be Reparented, and we suffer a failed assertion, and inaccurate return values.

Can anyone help me with this? Thank you very much.

#!/usr/bin/env python

import wx

class TestFrame(wx.Frame):

     def __init__(self):
         wx.Frame.__init__(self, None, -1, "Test")
         menuBar = wx.MenuBar()
         fileMenu = wx.Menu()
         item = fileMenu.Append(-1, text="Test &1")
         self.Bind(wx.EVT_MENU, self.OnTest1, item)
         item = fileMenu.Append(-1, text="Test &2")
         self.Bind(wx.EVT_MENU, self.OnTest2, item)
         item = fileMenu.Append(wx.ID_EXIT, text="&Quit")
         self.Bind(wx.EVT_MENU, self.OnQuit, item)
         menuBar.Append(fileMenu, "&File")
         self.SetMenuBar(menuBar)
         self.CreateStatusBar()
         clientSize = self.GetClientSize()
         sz1 = wx.Size(clientSize.width * .5, clientSize.height)
         sz2 = wx.Size(clientSize.width - sz1.width, clientSize.height)
         self.win1 = wx.Window(self, size = sz1)
         self.win1.SetBackgroundColour('blue')
         self.win2 = wx.Window(self, size = sz2, pos=wx.Point(sz1.width, 0))
         self.win2.SetBackgroundColour('red')
         self.subWin1 = wx.Window(self.win1, size=wx.Size(10,10))
         self.subWin2 = wx.Window(self.win2, size=wx.Size(20,20))

     def OnTest1(self, evt=None):
         print 'SubWin1:', self.subWin1.GetScreenRect()
         print 'SubWin2:', self.subWin2.GetScreenRect()

     def OnTest2(self, evt=None):
         self.subWin1.Reparent(self.win2)
         self.subWin2.Reparent(self.win1)
         print 'SubWin1:', self.subWin1.GetScreenRect()
         print 'SubWin2:', self.subWin2.GetScreenRect()

     def OnQuit(self, evt):
         self.Close()

app = wx.App()
frame = TestFrame()
frame.Centre()
frame.Show(True)
app.MainLoop()

I haven't used wxPython in a good while,

Welcome back.

and I'm afraid that I'm a
little rusty. I'm trying to get a program working using dynamically and
arbitrarily nested wxSplitterWindows. For this, the Reparent() method is
essential. Unfortunately, it seems that I'm unable to get accurate
screen coordinates of windows that have been re-parented. I fully
concede that I'm probably doing something wrong, but I can't figure out
what it is. If someone could steer me in the right direction, I would be
quite grateful.

I've cooked up a minimal example. If you run the example from the
terminal, and then select File->Test 1, the screen rectangle of the two
little windows will be correctly printed to standard output. But then if
you select File->Test 2, both of the little windows will be Reparented,
and we suffer a failed assertion, and inaccurate return values.

Can anyone help me with this? Thank you very much.

Whatever it was appears to have been fixed in 2.9. For 2.8 it looks like you can workaround the problem by delaying the code that needs the screen coordinates for a few ms. Probably GTK needs to do some things after the reparent has been done before it is valid again. It probably needs to wait for some response from the X server. See attached.

P.S. Next time don't forget to mention the platform and wx version.

reparent.py (1.74 KB)

···

On 5/17/12 1:32 AM, Scott wrote:

--
Robin Dunn
Software Craftsman