Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 3357192
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 18, 20262026-05-18T02:36:15+00:00 2026-05-18T02:36:15+00:00

I’d actually like to start by admitting that I’m terrified to ask this question.

  • 0

I’d actually like to start by admitting that I’m terrified to ask this question. That said, I have the following combination of classes:

A Dialog Class:

class formDialog(wx.Dialog):
  def __init__(self, parent, id = -1, panel = None, title = _("Unnamed Dialog"),
               modal = False, sizes = (400, -1)):
    wx.Dialog.__init__(self, parent, id, _(title),
                       style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER)

    if panel is not None:
      self._panel = panel(self)

      self._panel.SetSizeHints(*sizes)

      ds = wx.GridBagSizer(self._panel._gap, self._panel._gap)

      ds.Add(self._panel, (0, 0), (1, 1), wx.EXPAND | wx.ALL, self._panel._gap)

      ds.Add(wx.StaticLine(self), (1, 0), (1, 1), wx.EXPAND | wx.RIGHT | wx.LEFT, self._panel._gap)

      self.bs = self.CreateButtonSizer(self._panel._form['Buttons'])

      ds.Add(self.bs, (2, 0), (1, 1), wx.ALIGN_RIGHT | wx.ALL, self._panel._gap)

      ds.AddGrowableCol(0)
      ds.AddGrowableRow(0)

      self.SetSizerAndFit(ds)

      self.Center()

      self.Bind(wx.EVT_BUTTON, self._panel.onOk, id = wx.ID_OK)
      self.Bind(wx.EVT_BUTTON, self._panel.onClose, id = wx.ID_CANCEL)
      self.Bind(wx.EVT_CLOSE, self._panel.onClose)

      if modal:
        self.ShowModal()
      else:
        self.Show()

A Form Class:

class Form(wx.Panel):
  reqFields = [
    ('Defaults', {}),
    ('Disabled', [])
  ]

  def __init__(self, parent = None, id = -1, gap = 2, sizes = (-1, -1)):
    wx.Panel.__init__(self, parent, id)

    self.SetSizeHints(*sizes)

    self._gap = gap

    self.itemMap = {}

    if hasattr(self, '_form'):
      # There are a number of fields which need to exist in the form
      # dictionary.  Set them to defaults if they don't exist already.
      for k, d in self.reqFields:
        if not self._form.has_key(k):
          self._form[k] = d

      self._build()

  def _build(self):
    """
    The Build Method automates sizer creation and element placement by parsing
    a properly constructed object.
    """

    # The Main Sizer for the Panel.
    panelSizer = wx.GridBagSizer(self._gap, self._gap)

    # Parts is an Ordered Dictionary of regions for the form.
    for group, (key, data) in enumerate(self._form['Parts'].iteritems()):
      flags, sep, display = key.rpartition('-') #@UnusedVariable

      # HR signifies a Horizontal Rule for spacing / layout.  No Data Field.
      if display == 'HR':
        element = wx.StaticLine(self)

        style = wx.EXPAND

      # Any other value contains elements that need to be placed.
      else:
        element = wx.Panel(self, -1)

        # The Row Sizer
        rowSizer = wx.GridBagSizer(self._gap, self._gap)

        for row, field in enumerate(data):
          for col, item in enumerate(field):
            style = wx.EXPAND | wx.ALL

            pieces = item.split('-')

            # b for Buttons
            if pieces[0] == 'b':
              control = wx._controls.Button(element, -1, pieces[1])

            # custom items - Retrieve from the _form object
            if pieces[0] == 'custom':
              control = self._form[pieces[1]](element)

              # The row in the Grid needs to resize for Lists.
              panelSizer.AddGrowableRow(group)

              # Now the Row has to grow with the List as well.
              rowSizer.AddGrowableRow(row)

            # custom2 - Same as custom, but does not expand
            if pieces[0] == 'custom2':
              control = self._form[pieces[1]](element)

              style = wx.ALL

            # c for CheckBox
            if pieces[0] == 'c':
              control = wx.CheckBox(element, label = _(pieces[2]), name = pieces[1])

              control.SetValue(int(self._form['Defaults'].get(pieces[1], 0)))

            # d for Directory Picker
            if pieces[0] == 'd':
              control = wx.DirPickerCtrl(element, name = pieces[1])

              control.GetTextCtrl().SetEditable(False)

              control.GetTextCtrl().SetName(pieces[1])

              control.GetTextCtrl().SetValue(self._form['Defaults'].get(pieces[1], ''))

            # f for File Browser
            if pieces[0] == 'f':
              control = wx.FilePickerCtrl(element, name = pieces[1], wildcard = pieces[2])

              control.GetTextCtrl().SetEditable(False)

              control.GetTextCtrl().SetValue(self._form['Defaults'].get(pieces[1], ''))

            # f2 for Save File
            if pieces[0] == 'f2':
              control = wx.FilePickerCtrl(element, name = pieces[1],
                style = wx.FLP_SAVE | wx.FLP_OVERWRITE_PROMPT | wx.FLP_USE_TEXTCTRL,
                wildcard = pieces[2])

              control.GetTextCtrl().SetEditable(False)

            # h for Horizontal Rule - layout helper.
            if pieces[0] == 'h':
              control = wx.StaticLine(element)
              style = wx.EXPAND

            # l for Label (StaticText)
            if pieces[0] == 'l':
              control = wx.StaticText(element, label = _(pieces[1]))

              # Labels do not expand - override default style.
              style = wx.ALL | wx.ALIGN_CENTER_VERTICAL

            # p for Password (TextCtrl with Style)
            if pieces[0] == 'p':
              control = wx.TextCtrl(element, name = pieces[1], style = wx.TE_PASSWORD)

              control.SetValue(self._form['Defaults'].get(pieces[1], ''))

            # s for ComboBox (Select)
            if pieces[0] == 's':
              control = wx.ComboBox(element, name = pieces[1],
                choices = self._form['Options'].get(pieces[1], []),
                style = wx.CB_READONLY)

              control.SetValue(self._form['Defaults'].get(pieces[1], ''))

            # s2 for Spin Control
            if pieces[0] == 's2':
              control = wx.SpinCtrl(element, name = pieces[1], size = (55, -1),
                min = int(pieces[2]), max = int(pieces[3]))

              control.SetValue(int(self._form['Defaults'].get(pieces[1], 1)))

              # Spin Ctrl's do not expand.
              style = wx.ALL

            # t for TextCtrl
            if pieces[0] == 't':
              control = wx.TextCtrl(element, name = pieces[1])

              try:
                control.SetValidator(self._form['Validators'][pieces[1]])
              except KeyError: pass # No Validator Specified.

              control.SetValue(self._form['Defaults'].get(pieces[1], ''))

            # tr for Readonly TextCtrl
            if pieces[0] == 'tr':
              control = wx.TextCtrl(element, name = pieces[1], style = wx.TE_READONLY)

              control.SetValue(self._form['Defaults'].get(pieces[1], ''))

            # Check for elements disabled by default.  Store reference to 
            # Element in itemMap for reference by other objects later.
            if len(pieces) > 1:
              if pieces[1] in self._form['Disabled']:
                control.Enable(False)

              self.itemMap[pieces[1]] = control

            # Place the control in the row.
            rowSizer.Add(control, (row, col), (1, 1), style, self._gap)

            if style == wx.EXPAND | wx.ALL:
              rowSizer.AddGrowableCol(col)

        if 'NC' not in flags:
          sb = wx.StaticBox(element, -1, _(display))
          sz = wx.StaticBoxSizer(sb, wx.VERTICAL)

          sz.Add(rowSizer, 1, flag = wx.EXPAND)

          element.SetSizerAndFit(sz)
        else:
          element.SetSizerAndFit(rowSizer)

      panelSizer.Add(element, (group, 0), (1, 1), wx.EXPAND | wx.ALL, self._gap)

    panelSizer.AddGrowableCol(0)

    self.SetSizerAndFit(panelSizer)

  def getDescendants(self, elem, list):
    children = elem.GetChildren()

    list.extend(children)

    for child in children:
      self.getDescendants(child, list)

  def getFields(self):
    fields = []

    self.getDescendants(self, fields)

    # This removes children we can't retrieve values from.  This should result
    # in a list that only contains form fields, removing all container elements.
    fields = filter(lambda x: hasattr(x, 'GetValue'), fields)

    return fields

  def onOk(self, evt):
    self.onClose(evt)

  def onClose(self, evt):
    self.GetParent().Destroy()

The Form is meant to be used by subclassing like so:

class createQueue(Form):
  def __init__(self, parent):
    self._form = {
      'Parts' : OrderedDict([
        ('Queue Name', [
          ('t-Queue Name',)
        ])
      ]),
      'Buttons' : wx.OK | wx.CANCEL
    }

    Form.__init__(self, parent)

class generalSettings(Form):
  def __init__(self, parent):
    self._form = {
      'Parts': OrderedDict([
        ('Log Settings', [
          ('l-Remove log messages older than: ', 's2-interval-1-10', 's-unit')
        ]),
        ('Folder Settings', [
          ('l-Spool Folder Location:', 'd-dir'),
          ('l-Temp Folder Location:', 'd-temp')
        ]),
        ('Email Notifications', [
          ('l-Alert Email To:', 't-alert_to'),
          ('l-Alert Email From:', 't-alert_from'),
          ('l-Status Email From:', 't-status_from'),
          ('l-Alert Email Server:', 't-alert_host'),
          ('l-Login:', 't-alert_login'),
          ('l-Password:', 'p-alert_password')
        ]),
        ('Admin User', [
          ('c-req_admin-Require Admin Rights to make changes.',)
        ]),
        ('Miscellaneous', [
          ('l-Print Worker Tasks:', 's2-printtasks-1-256', 'l-Job Drag Options:', 's-jobdrop')
        ])
      ]),
      'Options': {
        'unit': ['Hours', 'Days', 'Months'],
        'jobdrop': ['Move Job to Queue', 'Copy Job to Queue']
      },
      'Buttons': wx.OK | wx.CANCEL
    }

    Form.__init__(self, parent)

These might be used like so:

formDialog(parent, panel = createQueue, title = 'Create a Queue', sizes = (200, -1))

formDialog(parent, panel = generalSettings, title = "General Settings")

Whew, that’s a ton, and thanks to anyone who makes it down this far. The idea is that I want something that takes care of the monotonous parts of layout in wxPython. I am designing a user interface that will need to create 100’s of different Dialogs and Forms. I wanted something that would allow me to generate the forms dynamically from a structured object.

I’d like to hear other developers’ thoughts on this kind of approach. The closest I’ve seen to something similar is Drupal’s Form API. I feel like it is viable for these reasons:

  • Easily rearrange fields.
  • No need to create / manage Sizers manually.
  • Compound / complex forms can be created easily.
  • Display helper elements (StaticBoxSizers, Static Lines) are easily added.

I am concerned that it is an undesirable approach for these reasons:

  • Long _build() function body in the Form Class.
  • May not be clear to other developers at first glance.
  • Uses Structured Strings to define fields.
  • There may be a better way.

Any thoughts, constructive, destructive, or otherwise will all be appreciated. Thanks!

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-18T02:36:15+00:00Added an answer on May 18, 2026 at 2:36 am

    You should also try wxFormDesigner or XRCed.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm parsing an RSS feed that has an ’ in it. SimpleXML turns this
I have some data like this: 1 2 3 4 5 9 2 6
this is what i have right now Drawing an RSS feed into the php,
I have a French site that I want to parse, but am running into
I have this code: - (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock { NSString *someString = [[NSString
link Im having trouble converting the html entites into html characters, (&# 8217;) i
Does anyone know how can I replace this 2 symbol below from the string
That's pretty much it. I'm using Nokogiri to scrape a web page what has
I have just tried to save a simple *.rtf file with some websites and
I ran into a problem. Wrote the following code snippet: teksti = teksti.Trim() teksti

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.