Almost There: 3 Custom Dialogs on a Notebook Page

Hi Rich,

Regardless, thanks to help from Chris B. I have something that almost works
(see attached). There's a raised, square panel in the upper left corner of
each staticBox and I've no idea what's generating that,

That was your pnl1, which is there without any reason, so let's throw it out.

and I cannot get the
StaticBox to surround the panels properly.

You need to use a StaticBoxSizer around your static box in which you
have to put the other sizer vbox1.

Some remarks:
- Try to use a consistent naming system: your use of capital letters
is random. There are many strategies. The one I follow is: Capitalized
for classes, UPPERCASE for constants and lowerCase for the rest.
Unfortunately wxPython uses capitalized letters for methods.

- You apperantly need to study the use of wx.EXPAND and proportion
when adding. Look good at the differences.

- self.SetSizerAndFit doesnt work for what you want to do

- I can recommend you to play with wxGlade. It writes neat code and
handles sizers very well. I learnt a lot by studying the code wxGlade
generated.

- WinPdb didn't crash for me. I was interested, as it would be the
first time that WinPdb would crash. Probably you are using Python
2.4.2 on which WinPdb doesn't catch unhandled exceptions and seems to
crash. This is a bug Nir Aides is working on.

Well, the beginning is always hard, but wxPython pays off quite fast!
I fixed your code and included it below. I think this what you were
after.

Good luck,
Stani

(BTW wxGlade & WinPdb ship with SPE, a Python IDE developped in
wxPython. You could probably learn from looking at SPE's dialog source
codes in _spe/dialogs. The preferences dialog box is the most complex
one.)

···

--

http://pythonide.stani.be/manual/html/manual.html
--
#!/usr/bin/env python2.4

#FramePanel:modScoping
"""
  This module has the user interface for the notebook tab named 'Scoping.'
"""

import wx

class ListPanel(wx.Panel):
  def __init__(self, prnt, Data):
    wx.Panel.__init__(self, prnt, wx.ID_ANY)

    Name = wx.StaticBox(self, wx.ID_ANY, Data['title'], size=wx.Size(185,550))
    Box = wx.StaticBoxSizer(Name, wx.VERTICAL)

    vbox1 = wx.BoxSizer(wx.VERTICAL)

    self.lc = wx.ListCtrl(self, wx.ID_ANY, size=wx.Size(175,200),
style=wx.LC_REPORT)
    self.lc.InsertColumn(0, 'Component')
    self.lc.SetColumnWidth(0, 175)
    self.tc1 = wx.TextCtrl(self, wx.ID_ANY)
    self.AddBut = wx.Button(self, wx.ID_ADD, '&Add')
    self.AddBut.Bind(wx.EVT_BUTTON, self.OnAdd)
    self.ClrBut = wx.Button(self, wx.ID_CLEAR, '&Clear')
    self.ClrBut.Bind(wx.EVT_BUTTON, self.OnClear)
    self.OkBut = wx.Button(self, wx.ID_OK, '&OK')
    self.OkBut.Bind(wx.EVT_BUTTON, self.OnOK)

    vbox1.Add(self.lc, 1, wx.EXPAND|wx.ALIGN_CENTER|wx.ALL, 5)
    vbox1.Add(self.tc1, 0, wx.ALIGN_CENTER|wx.ALL, 5)
    vbox1.Add(self.AddBut, 0, wx.ALIGN_CENTER|wx.ALL, 5)
    vbox1.Add(self.ClrBut, 0, wx.ALIGN_CENTER|wx.ALL, 5)
    vbox1.Add(self.OkBut, 0, wx.ALIGN_CENTER|wx.ALL, 5)
    Box.Add(vbox1,1,wx.EXPAND)

    self.SetAutoLayout(True)
    self.SetSizer(Box)
    Box.Fit(self)
    Box.SetSizeHints(self)
    self.Layout()

    self.Data =

  def OnAdd(self,event):
    if not self.tc1.GetValue():
      return
    num_items = self.lc.GetItemCount()
    self.lc.InsertStringItem(num_items, self.tc1.GetValue())
    self.tc1.Clear()

  def OnOK(self, event):
    Component = self.tc1.GetValue()
    self.Data = (Component)
    # check here if the data is valid.
    event.Skip() # this will let the event continue and be handles by
the usual OK event.

  def OnClear(self, event):
    self.tc1.Clear()

class modScoping(wx.Panel):
  """ Scoping is used with the FuzzyEI-Assessor model, forest sustainability
  model, and other models where public values and beliefs need to be
incorporated.

  There are three categories of components: Natural world, Economic,
and Social. Up
  to 8 components can be listed for each category. When done, the
names are used to
  produce LaTeX forms for the OMR reader. The input data are placed in
a symmetrical
  matrix and the principal eigenvector calculated. The results -- a vector of
  relative importance weights -- is displayed.
  """

  def __init__(self, prnt, ID):
    wx.Panel.__init__(self, prnt, wx.ID_ANY)

    topSizer = wx.BoxSizer(wx.VERTICAL)
    sidewaysBox = wx.BoxSizer(wx.HORIZONTAL)

    Data = {'title': "Natural:"}
    naturalPanel = ListPanel(self, Data)
    Data = {'title': "Economic:"}
    economicPanel = ListPanel(self, Data)
    Data = {'title': "Societal:"}
    socialPanel = ListPanel(self, Data)

    dividerLeft = wx.StaticLine(self, wx.ID_ANY, style=wx.LI_VERTICAL)
    dividerRight = wx.StaticLine(self, wx.ID_ANY, style=wx.LI_VERTICAL)
    sidewaysBox.Add(naturalPanel, 1, wx.EXPAND|wx.CENTER|wx.ALL, 5)
    sidewaysBox.Add(dividerLeft, 0, wx.EXPAND)
    sidewaysBox.Add(economicPanel, 1, wx.EXPAND|wx.CENTER|wx.ALL, 5)
    sidewaysBox.Add(dividerRight, 0, wx.EXPAND)
    sidewaysBox.Add(socialPanel, 1, wx.EXPAND|wx.CENTER|wx.ALL, 5)

    topSizer.Add(sidewaysBox, 1, wx.EXPAND|wx.ALL, 5)

    self.SetAutoLayout(True)
    self.SetSizer(topSizer)
    topSizer.Fit(self)
    topSizer.SetSizeHints(self)
    self.Layout()

class MyApp(wx.App):
  def OnInit(self):
    frame = wx.Frame(None, wx.ID_ANY)
    Panel = modScoping(frame, wx.ID_ANY)
    frame.Fit()
    frame.Layout()
    frame.Show(True)
    return True

app = MyApp(0)
app.MainLoop()

Some remarks:
- Try to use a consistent naming system: your use of capital letters
is random. There are many strategies. The one I follow is: Capitalized
for classes, UPPERCASE for constants and lowerCase for the rest.
Unfortunately wxPython uses capitalized letters for methods.

Stani,

   I like the mixedcase format, but am willing to conform to another standard
instead.

- You apperantly need to study the use of wx.EXPAND and proportion when
adding. Look good at the differences.

   I understand what both GROW and PROPORTION do, but still don't apply them
appropriately. Some times I get them in the wrong place in sizers, and I
guess that's part of what I did here.

- self.SetSizerAndFit doesnt work for what you want to do

   A-ha! That's good to know. Is there some documentation that will help me
understand what sizing and fitting to use in different situations? The
wxWidgets book is quite sparse on this subject.

- I can recommend you to play with wxGlade. It writes neat code and handles
sizers very well. I learnt a lot by studying the code wxGlade generated.

   I started using it and was able to generate several first drafts. Yes, it
is an excellent tool.

- WinPdb didn't crash for me. I was interested, as it would be the first
time that WinPdb would crash. Probably you are using Python 2.4.2 on which
WinPdb doesn't catch unhandled exceptions and seems to crash. This is a bug
Nir Aides is working on.

   No, python-2.4.1. Patrick will put 2.4.2 with the next Slackware release.
I'm sure it was my code that caused it to become totally confused.

Well, the beginning is always hard, but wxPython pays off quite fast!
I fixed your code and included it below. I think this what you were
after.

   Thank you very much. It is just what I was trying to achieve. I know that
it's a matter of familiarity and use. Among the eight notebook pages I have a
variety of layouts and each requires different knowledge. I've learned quite
a bit from all of you here as I've come across new situations I cannot
resolve from reading the wxWidgets book or the wiki.

Rich

···

On Fri, 16 Dec 2005, SPE Stani's Python Editor wrote:

--
Richard B. Shepard, Ph.D. | Author of "Quantifying Environmental
Applied Ecosystem Services, Inc. (TM) | Impact Assessments Using Fuzzy Logic"
<http://www.appl-ecosys.com> Voice: 503-667-4517 Fax: 503-667-8863