Newbie frame-in-frame question, updated

OK, let me try again. Here's a similar example using a grid bag sizer. The code creates four child frames, and the parent panel resizes to hold them, but it doesn't actually hold them; where they display has nothing to do with where the main frame and panel are.

What do I need to do to this code so that the panel actually =contains= the child frames?

import wx

class MainFrame(wx.Frame):
     def __init__(self, parent, id, title):
         wx.Frame.__init__(self, parent, -1, title)
         pnl = wx.Panel(self,-1)
         gbs = wx.GridBagSizer(2, 2)
         win1 = gbs.Add(ChildFrame(pnl, -1,"win1"),(0,0),flag=wx.EXPAND)
         win2 = gbs.Add(ChildFrame(pnl, -1,"win2"),(0,1),flag=wx.EXPAND)
         win3 = gbs.Add(ChildFrame(pnl, -1,"win3"),(1,0),flag=wx.EXPAND)
         win4 = gbs.Add(ChildFrame(pnl, -1,"win4"),(1,1),flag=wx.EXPAND)
         pnl.SetSizerAndFit(gbs)
         self.SetClientSize(pnl.GetSize())

class ChildFrame(wx.Frame):
     def __init__(self, parent, id, title):
         wx.Frame.__init__(self, parent, -1, title, size = (300, 300))
         self.Show(True)

if __name__ == '__main__':
     app = wx.App(redirect=False)
     frame = MainFrame(None, -1, "Frame in frame test")
     frame.Show()
     app.MainLoop()

Bob

···

Date: Tue, 24 Oct 2006 22:40:38 -0400
To: wxPython-users@lists.wxwidgets.org
From: Bob Klahn <bobstones@comcast.net>
Subject: [wxPython-users] Newbie frame-in-frame question

A VERY basic question: What do I need to add or change to get the child frames inside the panel?

import wx

class MainFrame(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, -1, title)
        pnl = wx.Panel(self,-1)
        win1 = ChildFrame(pnl, -1, "win 1")
        win2 = ChildFrame(pnl, -1, "win 2")

class ChildFrame(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, -1, title, size = (300, 300))
        self.Show(True)

if __name__ == '__main__':
    app = wx.App(redirect=False)
    frame = MainFrame(None, -1, "Frame in frame test")
    frame.Show()
    app.MainLoop()

Bob

--
No virus found in this outgoing message.
Checked by AVG Free Edition.
Version: 7.0.408 / Virus Database: 268.13.11/494 - Release Date: 10/24/2006

---------------------------------------------------------------------
To unsubscribe, e-mail: wxPython-users-unsubscribe@lists.wxwidgets.org
For additional commands, e-mail: wxPython-users-help@lists.wxwidgets.org

--
No virus found in this incoming message.
Checked by AVG Free Edition.
Version: 7.0.408 / Virus Database: 268.13.11/494 - Release Date: 10/24/2006

--
No virus found in this outgoing message.
Checked by AVG Free Edition.
Version: 7.0.408 / Virus Database: 268.13.11/494 - Release Date: 10/24/2006

There are two kinds of "top-level" windows that cannot be embedded in
other windows: wx.Dialog and wx.Frame (and subclasses thereof). You
cannot, according to my understanding of wxPython, perform what you want
to do using wx.Frames.

If all you want is some sort of GUI object that can hold other objects
all together, take your pick: wx.Window, wx.Panel, wx.SplitterWindow,
wx.SashWindow, etc.

If you tell us what you want, not in terms of what you think should work,
but in terms of the *functionality* you want, we can offer more
suggestions. You may also find answers by looking in the wxPython demo,
which is available for Windows here:
http://prdownloads.sourceforge.net/wxpython/wxPython2.7-win32-docs-demos-2.7.1.2.exe
Or linux/OSX here:
http://prdownloads.sourceforge.net/wxpython/wxPython-demo-2.7.1.2.tar.bz2

- Josiah

···

Bob Klahn <bobstones@comcast.net> wrote:

OK, let me try again. Here's a similar example using a grid bag
sizer. The code creates four child frames, and the parent panel
resizes to hold them, but it doesn't actually hold them; where they
display has nothing to do with where the main frame and panel are.

What do I need to do to this code so that the panel actually
=contains= the child frames?

Ah, that's the basic fact I was missing. This revised code works:

import wx

class MainFrame(wx.Frame):
     def __init__(self, parent, id, title):
         wx.Frame.__init__(self, parent, -1, title)
         pnl = wx.Panel(self,-1)
         gbs = wx.GridBagSizer(1, 1)
         win1 = gbs.Add(ChildWindow(pnl, -1),(0,0),flag=wx.EXPAND)
         win2 = gbs.Add(ChildWindow(pnl, -1),(0,1),flag=wx.EXPAND)
         win3 = gbs.Add(ChildWindow(pnl, -1),(1,0),flag=wx.EXPAND)
         win4 = gbs.Add(ChildWindow(pnl, -1),(1,1),flag=wx.EXPAND)
         pnl.SetSizerAndFit(gbs)
         self.SetClientSize(pnl.GetSize())

class ChildWindow(wx.Window):
     def __init__(self, parent, id):
         wx.Window.__init__(self, parent, -1, size=(300,300))
         self.SetBackgroundColour(wx.BLUE)

if __name__ == '__main__':
     app = wx.App(redirect=False)
     frame = MainFrame(None, -1, "Windows in panel in frame test")
     frame.Show()
     app.MainLoop()

···

At 03:29 AM 10/25/2006, Josiah wrote:

Bob Klahn <bobstones@comcast.net> wrote:
> Here's a similar example using a grid bag
> sizer. The code creates four child frames, and the parent panel
> resizes to hold them, but it doesn't actually hold them; where they
> display has nothing to do with where the main frame and panel are.
>
> What do I need to do to this code so that the panel actually
> =contains= the child frames?

There are two kinds of "top-level" windows that cannot be embedded in
other windows: wx.Dialog and wx.Frame (and subclasses thereof). You
cannot, according to my understanding of wxPython, perform what you want
to do using wx.Frames.

_______________________________________________________

Now I need to think about how I'm going to manage child window titling,
how I'm going to manage child window resizing, etc.

If all you want is some sort of GUI object that can hold other objects
all together, take your pick: wx.Window, wx.Panel, wx.SplitterWindow,
wx.SashWindow, etc.

My examples used wx.Panel. As I said above, I simply didn't realize I
couldn't put a frame inside a frame. That makes perfect sense now.

If you tell us what you want, not in terms of what you think should work,
but in terms of the *functionality* you want, we can offer more
suggestions.

Where I'm coming from: I have a single-window program that handles one
problem at a time. What I'm trying to do is to replicate that functionality so
that I can have multiple related problems on screen at the same time.

Sooooooo, now I want to put one-line titles above each of the four windows
in my example, and a border around each title-window pair. Each title would
presumably be a static text control. How would you all manage the overall
layout of just that much?

You may also find answers by looking in the wxPython demo,
which is available for Windows here:
Download wxPython2.7-win32-docs-demos-2.7.1.2.exe (wxPython)

I have that, and I continue to study it.

Bob

--
No virus found in this outgoing message.
Checked by AVG Free Edition.
Version: 7.0.408 / Virus Database: 268.13.11/494 - Release Date: 10/24/2006

Hi Bob,

Where I'm coming from: I have a single-window program that
handles one problem at a time. What I'm trying to do is to
replicate that functionality so that I can have multiple
related problems on screen at the same time.

Sooooooo, now I want to put one-line titles above each of the
four windows in my example, and a border around each
title-window pair. Each title would presumably be a static
text control. How would you all manage the overall layout of
just that much?

In my opinion, you have 3 alternatives:

1) Easy, but somewhat not recommended by Microsoft (!), as they say it is obsolete:

Use MDIFrames (Multiple Document Interface). It is something like a big father frame that holds inside smaller frames. All the child frames have its own titlebar. Though someone has deprecated the use of MDI things, I still see around good apps written with the MDI philosophy;

2) Medium:

Use wxAUI. If you have a wxPython version >= 2.7.0.1 installed, there is a sample in the demo. If not, you could use PyAUI that is the Python translation of it and it works almost in the same way. wxAUI gives you the advantage that you should no more bother about the layout: once you decide how you want to position your windows, you're done. Plus you can put your title in nice "titlebars" that wxAUI creates for you for every pane. It may be problematic, however, if you really need some specific positioning and relative sizing of the windows.

3) Hard:

Do the layout yourself. You could construct a vertical wx.BoxSizer for every window: the top part of the sizer contains the wx.StaticText (with proportion 0), while the bottom part contains your main window (with proportion 1 and wx.EXPAND flag, so that it expands to fill all the space left by the static text). So now you have a sizer for every window, and you should decide how to arrange them all together. You can still use sizer to construct the most complex layout you want, but here itr just depends on how you really want to layout your app.

Andrea.

···

_________________________________________
Andrea Gavana (gavana@kpo.kz)
Reservoir Engineer
KPDL
4, Millbank
SW1P 3JA London

Direct Tel: +44 (0) 20 717 08936
Mobile Tel: +44 (0) 77 487 70534
Fax: +44 (0) 20 717 08900
Web: http://xoomer.virgilio.it/infinity77
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

Hi Bob,

> Where I'm coming from: I have a single-window program that
> handles one problem at a time. What I'm trying to do is to
> replicate that functionality so that I can have multiple
> related problems on screen at the same time.
>
> Sooooooo, now I want to put one-line titles above each of the
> four windows in my example, and a border around each
> title-window pair. Each title would presumably be a static
> text control. How would you all manage the overall layout of
> just that much?

In my opinion, you have 3 alternatives:

1) Easy, but somewhat not recommended by Microsoft (!), as they say it is obsolete:

Use MDIFrames (Multiple Document Interface). It is something like a big father frame that holds inside smaller frames. All the child frames have its own titlebar. Though someone has deprecated the use of MDI things, I still see around good apps written with the MDI philosophy;

Deprecation, what a word. From the Latin "to pray." "We pray you won't use this any more." Or "If you continue to use this, say your prayers." I love it.

2) Medium:

Use wxAUI. If you have a wxPython version >= 2.7.0.1 installed, there is a sample in the demo. If not, you could use PyAUI that is the Python translation of it and it works almost in the same way. wxAUI gives you the advantage that you should no more bother about the layout: once you decide how you want to position your windows, you're done. Plus you can put your title in nice "titlebars" that wxAUI creates for you for every pane. It may be problematic, however, if you really need some specific positioning and relative sizing of the windows.

Thanks, I'll look at that one more closely. But I will need specific positioning and relative sizing of the windows down the road, so I think I'll be moving on to ...

3) Hard:

Do the layout yourself. You could construct a vertical wx.BoxSizer for every window: the top part of the sizer contains the wx.StaticText (with proportion 0), while the bottom part contains your main window (with proportion 1 and wx.EXPAND flag, so that it expands to fill all the space left by the static text). So now you have a sizer for every window, and you should decide how to arrange them all together. You can still use sizer to construct the most complex layout you want, but here itr just depends on how you really want to layout your app.

Got it, Andrea. Thank you very much. BTW, I like your web site. You and Sofia are truly blessed.

Bob

···

At 09:35 AM 10/25/2006, Andrea wrote:

--
No virus found in this outgoing message.
Checked by AVG Free Edition.
Version: 7.0.408 / Virus Database: 268.13.11/494 - Release Date: 10/24/2006

Bob Klahn wrote:

Ah, that's the basic fact I was missing. This revised code works:

you got it.

Just a note: if you are going to put any other controls on ChildWindow, you'll probably want to use wx.Panel, rather than wx.Window.

···

class ChildWindow(wx.Window):
    def __init__(self, parent, id):
        wx.Window.__init__(self, parent, -1, size=(300,300))
        self.SetBackgroundColour(wx.BLUE)

--
Christopher Barker, Ph.D.
Oceanographer
                                         
NOAA/OR&R/HAZMAT (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@noaa.gov