After minimize/restore, several wx.Frame's showing order changed

Windows 10, wxPython 4.0.6, Python 3.7.4
I create several sub wx.Frame with style: wx.MINIMIZE_BOX | wx.FRAME_NO_TASKBAR | wx.FRAME_FLOAT_ON_PARENT. When sub frames are showing, after minimize->restore the main frame by clicking the icon on taskbar, the sub frames’ showing order are changed.
Sample code:

import wx

class MainFrame(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, id=-1, parent=parent, size=wx.Size(600, 500),
                          title='Test')
        self.panel = wx.Panel(self, id=-1, pos=(200, 300))
        self.button = wx.Button(self.panel, id=-1, label='button',
                                 pos=wx.Point(20, 56), size=wx.Size(87, 28))
        self.button.Bind(wx.EVT_BUTTON, self.OnButton, id=-1)
        self.frame1 = MyFrame(self, 'frame1')
        self.frame2 = MyFrame(self, 'frame2')
        self.frame3 = MyFrame(self, 'frame3')

    def OnButton(self, event):
        self.frame1.Show()
        self.frame2.Show()
        self.frame3.Show()

        event.Skip()

class MyFrame(wx.Frame):
    def __init__(self, parent, title):
        style = wx.SYSTEM_MENU | wx.CAPTION | wx.CLOSE_BOX | \
                wx.MINIMIZE_BOX | wx.FRAME_NO_TASKBAR | wx.FRAME_FLOAT_ON_PARENT
        wx.Frame.__init__(self, id=-1, parent=parent, size=wx.Size(300, 200),
                          title=title, style=style)
        
if __name__ == '__main__':
    app = wx.App()
    frame = MainFrame(None)
    frame.Show()
    app.MainLoop()

Operations:

  1. Click the button.
    ->The order (from bottom to top): frame1->frame2->frame3
  2. Click the icon on taskbar to minimize, then restore.
    ->The order changed (from bottom to top): frame1->frame3->frame2

Linda,

See attached file, play with it and customize as needed.

ForLinda - wx.Frame - subframe ordering.py (1.9 KB)

Sláinte,
Thom

Try to use a vertical BoxSizer. Add frame1, frame2 et frame3 to the sizer.

Edit : the button should be added to the sizer. The sizer should be applied to the panel. All elements (button, frames) should be child of the panel.

Thom,
Thank you for the attachment. But how can I restore the showing order of frames same as the order before minimized. For example, if I set focus to frame2, changing the showing order to be frame1->frame3->frame2. After minimize->restore, how to restore to be the same order?

Linda

One could create a list that keeps track of the desired focus order for your subframes. Update the list at every EVT_SET_FOCUS event, i.e. the clicked (focused) subframe should be moved 1st in list.

Operations:

  1. list = [1,2,3], in __init__
  2. click frame2 -> update: list = [2,1,3]
  3. walk the list (reversed) on restore and show the corresponding subframe
  4. be creative

Good luck filling in the rest of the missing blanks yourself.

If use the BoxSizer, sub frames can not be dragged anywhere of the screen. Is that so? But I need subframes can be dragged anywhere.

Thom,
Sorry for late. I used EVT_SET_FOCUS event to count the orders of subframes, but still has problem. When it is restored, all frames are restored in order as my specified list, but after that, frame 2 is set focus unexpectedly. For example, if the list is [1, 2, 3] before minimized, after restore, it changed to be [1, 3, 2].
Please help to check what’s wrong in code?minimized-error.py (2.7 KB)

Linda

Linda,

After a quick code scan it generally seems ok. Have to look into it later this afternoon…

For now - if you haven’t done this yet - I suggest you first debug/watch the relevant events with WIT aka Widget Inspection Tool. I suspect that EVT_SET_FOCUS itself triggers an unhandled EVT_CHILD_FOCUS (sub)event which might disrupt things.

Thom

Thom,
I have used inspection tool, but it seems there is a little difference. When using the inspection tool, after restore, list is changed from [1,2,3] to [2,3,1]. In the last, subframe1’s EVT_CHILD_FOCUS event is triggered.
Minimize&Restore
Linda