commit-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commit-gnuradio] r10752 - in gnuradio/branches/features/experimental-gu


From: jblum
Subject: [Commit-gnuradio] r10752 - in gnuradio/branches/features/experimental-gui: . forms
Date: Thu, 2 Apr 2009 19:20:48 -0600 (MDT)

Author: jblum
Date: 2009-04-02 19:20:48 -0600 (Thu, 02 Apr 2009)
New Revision: 10752

Added:
   gnuradio/branches/features/experimental-gui/forms/
   gnuradio/branches/features/experimental-gui/forms/__init__.py
   gnuradio/branches/features/experimental-gui/forms/converters.py
   gnuradio/branches/features/experimental-gui/forms/forms.py
Removed:
   gnuradio/branches/features/experimental-gui/forms.py
Log:
Added enable/disable feature. Added log slider and converter.
Created forms package with converters and forms modules.



Added: gnuradio/branches/features/experimental-gui/forms/__init__.py
===================================================================
--- gnuradio/branches/features/experimental-gui/forms/__init__.py               
                (rev 0)
+++ gnuradio/branches/features/experimental-gui/forms/__init__.py       
2009-04-03 01:20:48 UTC (rev 10752)
@@ -0,0 +1,40 @@
+#
+# Copyright 2009 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+"""
+The following classes will be available through gnuradio.wxgui.forms:
+""" 
+
+########################################################################
+# External Converters
+########################################################################
+from converters import \
+       eval_converter, str_converter, \
+       float_converter, int_converter
+
+########################################################################
+# External Forms
+########################################################################
+from forms import \
+       radio_buttons, drop_down, notebook, \
+       button, toggle_button, single_button, \
+       check_box, text_box, static_text, \
+       slider, log_slider

Added: gnuradio/branches/features/experimental-gui/forms/converters.py
===================================================================
--- gnuradio/branches/features/experimental-gui/forms/converters.py             
                (rev 0)
+++ gnuradio/branches/features/experimental-gui/forms/converters.py     
2009-04-03 01:20:48 UTC (rev 10752)
@@ -0,0 +1,143 @@
+#
+# Copyright 2009 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import eng_notation
+import math
+
+class abstract_converter(object):
+       def external_to_internal(self, v):
+               """
+               Convert from user specified value to value acceptable to 
underlying primitive.
+               The underlying primitive usually expects strings.
+               """
+               raise NotImplementedError
+       def internal_to_external(self, s):
+               """
+               Convert from underlying primitive value to user specified value.
+               The underlying primitive usually expects strings.
+               """
+               raise NotImplementedError
+       def help(self):
+               return "Any string is acceptable"
+
+class identity_converter(abstract_converter):
+       def external_to_internal(self,v):
+               return v
+       def internal_to_external(self, s):
+               return s
+
+########################################################################
+# Commonly used converters
+########################################################################
+class chooser_converter(abstract_converter):
+       """
+       Convert between a set of possible choices and an index.
+       Used in the chooser base and all sub-classes.
+       """
+       def __init__(self, choices):
+               self._choices = choices
+       def external_to_internal(self, choice):
+               return self._choices.index(choice)
+       def internal_to_external(self, index):
+               return self._choices[index]
+       def help(self):
+               return 'Enter a possible value in choices: 
"%s"'%str(self._choices)
+
+class bool_converter(abstract_converter):
+       """
+       The internal representation is boolean.
+       The external representation is specified.
+       Used in the check box form.
+       """
+       def __init__(self, true, false):
+               self._true = true
+               self._false = false
+       def external_to_internal(self, v):
+               return bool(v)
+       def internal_to_external(self, v):
+               if v: return self._true
+               else: return self._false
+       def help(self):
+               return "Value must be cast-able to type bool."
+
+class eval_converter(abstract_converter):
+       """
+       A catchall converter when int and float are not enough.
+       Evaluate the internal representation with python's eval().
+       Possible uses, set a complex number, constellation points.
+       Used in text box.
+       """
+       def external_to_internal(self, s):
+               return str(s)
+       def internal_to_external(self, s):
+               return eval(s)
+       def help(self):
+               return "Value must be evaluatable by python's eval."
+
+class str_converter(abstract_converter):
+       def external_to_internal(self, v):
+               return str(v)
+       def internal_to_external(self, s):
+               return str(s)
+
+class int_converter(abstract_converter):
+       def external_to_internal(self, v):
+               return str(v)
+       def internal_to_external(self, s):
+               return int(s, 0)
+       def help(self):
+               return "Enter an integer.  Leading 0x indicates hex"
+
+class float_converter(abstract_converter):
+       def external_to_internal(self, v):
+               return eng_notation.num_to_str(v)
+       def internal_to_external(self, s):
+               return eng_notation.str_to_num(s)
+       def help(self):
+               return "Enter a float with optional scale suffix.  E.g., 100.1M"
+
+class slider_converter(abstract_converter):
+       """
+       Scale values to and from the slider.
+       """
+       def __init__(self, minimum, maximum, num_steps, cast):
+               assert minimum < maximum
+               assert num_steps > 0
+               self._offset = minimum
+               self._scaler = float(maximum - minimum)/num_steps
+               self._cast = cast
+       def external_to_internal(self, v):
+               return int(round((v - self._offset)/self._scaler))
+       def internal_to_external(self, v):
+               return self._cast(v*self._scaler + self._offset)
+       def help(self):
+               return "Value should be within slider range"
+
+class log_slider_converter(slider_converter):
+       def __init__(self, min_exp, max_exp, num_steps, base):
+               assert min_exp < max_exp
+               assert num_steps > 0
+               self._base = base
+               slider_converter.__init__(self, minimum=min_exp, 
maximum=max_exp, num_steps=num_steps, cast=float)
+       def external_to_internal(self, v):
+               return slider_converter.external_to_internal(self, math.log(v, 
self._base))
+       def internal_to_external(self, v):
+               return self._base**slider_converter.internal_to_external(self, 
v)

Copied: gnuradio/branches/features/experimental-gui/forms/forms.py (from rev 
10738, gnuradio/branches/features/experimental-gui/forms.py)
===================================================================
--- gnuradio/branches/features/experimental-gui/forms/forms.py                  
        (rev 0)
+++ gnuradio/branches/features/experimental-gui/forms/forms.py  2009-04-03 
01:20:48 UTC (rev 10752)
@@ -0,0 +1,478 @@
+#
+# Copyright 2009 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+"""
+The forms module contains general purpose wx-gui forms for gnuradio apps.
+
+The forms follow a layered model:
+  * internal layer
+    * deals with the wxgui objects directly
+    * implemented in event handler and update methods
+  * translation layer
+    * translates the between the external and internal layers
+    * handles parsing errors between layers
+  * external layer 
+    * provided external access to the user
+    * set_value, get_value, and optional callback
+    * set and get through optional pubsub and key
+"""
+
+EXT_KEY = 'external'
+INT_KEY = 'internal'
+
+import wx
+import sys
+from gnuradio.gr.pubsub import pubsub
+import converters
+
+########################################################################
+# Base Class Form
+########################################################################
+class _form_base(pubsub, wx.BoxSizer):
+       def __init__(self, parent=None, sizer=None, proportion=0, 
style=wx.HORIZONTAL, ps=None, key='', value=None, callback=None, 
converter=converters.identity_converter()):
+               pubsub.__init__(self)
+               wx.BoxSizer.__init__(self, style)
+               self._parent = parent
+               self._converter = converter
+               self._widgets = list()
+               #add to the sizer if provided
+               if sizer: sizer.Add(self, proportion, wx.EXPAND)
+               #proxy the pubsub and key into this form
+               if ps is not None:
+                       assert key
+                       self.proxy(EXT_KEY, ps, key)
+               #no pubsub passed, must set initial value
+               else: self.set_value(value)
+               #subscribe callbacks for changes
+               self.subscribe(INT_KEY, self._update)
+               self.subscribe(INT_KEY, self._translate_internal_to_external)
+               self.subscribe(EXT_KEY, self._translate_external_to_internal)
+               if callback: self.subscribe(EXT_KEY, callback)
+
+       def _add_widget(self, widget, label='', proportion=0, 
label_proportion=1, style=wx.HORIZONTAL):
+               """
+               Add the main widget to this object sizer.
+               If label is passed, add a label as well.
+               Register the widget and the label in the widgets list (for 
enable/disable).
+               @param widget the main widget
+               @param label the optional label
+               @param proportion the widget proportion when added to this sizer
+               @param label_proportion the label proportion when added to this 
sizer
+               @param style wx.HORIZONTAL or wx.VERTICAL
+               """
+               self._widgets.append(widget)
+               if not label: wx.BoxSizer.Add(self, widget, proportion, 
wx.EXPAND)
+               else:
+                       label_style, widget_style = {
+                               wx.HORIZONTAL: (wx.ALIGN_CENTER_VERTICAL | 
wx.ALIGN_LEFT, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT), 
+                               wx.VERTICAL: (wx.ALIGN_CENTER_HORIZONTAL | 
wx.ALIGN_TOP, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_BOTTOM), 
+                       }[style]
+                       label_text = wx.StaticText(self._parent, label=' %s: 
'%label)
+                       self._widgets.append(label_text)
+                       self.Add(label_text, label_proportion, label_style)
+                       self.Add(widget, proportion, widget_style)
+
+       def _translate_external_to_internal(self, external):
+               try:
+                       internal = 
self._converter.external_to_internal(external)
+                       #prevent infinite loop between internal and external 
pubsub keys by only setting if changed
+                       if self[INT_KEY] != internal: self[INT_KEY] = internal
+               except Exception, e:
+                       self._err_msg(external, e)
+                       self[INT_KEY] = self[INT_KEY] #reset to last good 
setting
+
+       def _translate_internal_to_external(self, internal):
+               try:
+                       external = 
self._converter.internal_to_external(internal)
+                       #prevent infinite loop between internal and external 
pubsub keys by only setting if changed
+                       if self[EXT_KEY] != external: self[EXT_KEY] = external
+               except Exception, e:
+                       self._err_msg(internal, e)
+                       self[EXT_KEY] = self[EXT_KEY] #reset to last good 
setting
+
+       def _err_msg(self, value, e):
+               print >> sys.stderr, 'Error translating value: 
"%s"\n\t%s\n\t%s'%(value, e, self._converter.help())
+
+       #call after gui is setup to initialize
+       def _init(self): self[EXT_KEY] = self[EXT_KEY]
+
+       #override in subclasses to handle the wxgui object
+       def _update(self, value): raise NotImplementedError
+       def _handle(self, event): raise NotImplementedError
+
+       #provide a set/get interface for this form
+       def get_value(self): return self[EXT_KEY]
+       def set_value(self, value): self[EXT_KEY] = value
+
+       def Disable(self, disable=True): self.Enable(not disable)
+       def Enable(self, enable=True):
+               if enable:
+                       for widget in self._widgets: widget.Enable()
+               else:
+                       for widget in self._widgets: widget.Disable()
+
+########################################################################
+# Static Text Form
+########################################################################
+class static_text(_form_base):
+       def __init__(self, label='', width=-1, bold=False, **kwargs):
+               _form_base.__init__(self, converter=converters.str_converter(), 
**kwargs)
+               self._static_text = wx.StaticText(self._parent, 
size=wx.Size(width, -1))
+               if bold:
+                       font = self._static_text.GetFont()
+                       font.SetWeight(wx.FONTWEIGHT_BOLD)
+                       self._static_text.SetFont(font)
+               self._add_widget(self._static_text, label)
+               self._init()
+
+       def _update(self, label): self._static_text.SetLabel(label)
+
+########################################################################
+# Text Box Form
+########################################################################
+class text_box(_form_base):
+       def __init__(self, label='', width=-1, **kwargs):
+               _form_base.__init__(self, 
converter=converters.eval_converter(), **kwargs)
+               self._text_box = wx.TextCtrl(self._parent, size=wx.Size(width, 
-1), style=wx.TE_PROCESS_ENTER)
+               self._add_widget(self._text_box, label)
+               self._text_box.Bind(wx.EVT_TEXT_ENTER, self._handle)
+               self._init()
+
+       def _handle(self, event): self[INT_KEY] = self._text_box.GetValue()
+       def _update(self, value): self._text_box.SetValue(value)
+
+########################################################################
+# Slider Form
+########################################################################
+class slider(_form_base):
+       """
+       A generic linear slider.
+       @param cast a cast function, int, or float (default=float)
+       @param length the length of the slider in px
+       @param style wx.SL_HORIZONTAL or wx.SL_VERTICAL
+       """
+       def __init__(self, label='', length=-1, minimum=-100, maximum=100, 
num_steps=100, cast=float, style=wx.SL_HORIZONTAL, converter=None, **kwargs):
+               if not converter:
+                       converter = 
converters.slider_converter(minimum=minimum, maximum=maximum, 
num_steps=num_steps, cast=cast)
+               _form_base.__init__(self, converter=converter, style=style, 
**kwargs)
+               if style & wx.SL_HORIZONTAL:
+                       slider_size = wx.Size(length, -1)
+                       label_style = wx.HORIZONTAL
+               elif style & wx.SL_VERTICAL:
+                       slider_size = wx.Size(-1, length)
+                       label_style = wx.VERTICAL
+               else: raise NotImplementedError
+               self._slider = wx.Slider(self._parent, minValue=0, 
maxValue=num_steps, size=slider_size, style=style)
+               self._add_widget(self._slider, label, proportion=1, 
style=label_style)
+               self._slider.Bind(wx.EVT_SCROLL, self._handle)
+               self._init()
+
+       def _handle(self, event): self[INT_KEY] = self._slider.GetValue()
+       def _update(self, value): self._slider.SetValue(value)
+
+class log_slider(slider):
+       """
+       A generic log slider.
+       """
+       def __init__(self, min_exp=0, max_exp=1, base=10, num_steps=100, 
converter=None, **kwargs):
+               if not converter:
+                       converter = 
converters.log_slider_converter(min_exp=min_exp, max_exp=max_exp, 
num_steps=num_steps, base=base)
+               slider.__init__(self, converter=converter, **kwargs)
+
+########################################################################
+# Check Box Form
+########################################################################
+class check_box(_form_base):
+       def __init__(self, label='', true=True, false=False, **kwargs):
+               _form_base.__init__(self, 
converter=converters.bool_converter(true=true, false=false), **kwargs)
+               self._check_box = wx.CheckBox(self._parent, 
style=wx.CHK_2STATE, label=label)
+               self._add_widget(self._check_box)
+               self._check_box.Bind(wx.EVT_CHECKBOX, self._handle)
+               self._init()
+
+       def _handle(self, event): self[INT_KEY] = self._check_box.IsChecked()
+       def _update(self, checked): self._check_box.SetValue(checked)
+
+########################################################################
+# Base Class Chooser Form
+########################################################################
+class _chooser_base(_form_base):
+       def __init__(self, choices=[], labels=None, **kwargs):
+               _form_base.__init__(self, 
converter=converters.chooser_converter(choices), **kwargs)
+               self._choices = choices
+               self._labels = map(str, labels or choices)
+
+########################################################################
+# Drop Down Chooser Form
+########################################################################
+class drop_down(_chooser_base):
+       def __init__(self, label='', **kwargs):
+               _chooser_base.__init__(self, **kwargs)
+               self._drop_down = wx.Choice(self._parent, choices=self._labels)
+               self._add_widget(self._drop_down, label)
+               self._drop_down.Bind(wx.EVT_CHOICE, self._handle)
+               self._init()
+
+       def _handle(self, event): self[INT_KEY] = self._drop_down.GetSelection()
+       def _update(self, i): self._drop_down.SetSelection(i)
+
+########################################################################
+# Button Chooser Form
+#  Circularly move through the choices with each click.
+#  Can be a single-click button with one choice.
+#  Can be a 2-state button with two choices.
+########################################################################
+class button(_chooser_base):
+       def __init__(self, label='', style=0, width=-1, **kwargs):
+               _chooser_base.__init__(self, **kwargs)
+               self._button = wx.Button(self._parent, size=wx.Size(width, -1), 
style=style)
+               self._add_widget(self._button, label)
+               self._button.Bind(wx.EVT_BUTTON, self._handle)
+               self._init()
+
+       def _handle(self, event): self[INT_KEY] = (self[INT_KEY] + 
1)%len(self._choices) #circularly increment index
+       def _update(self, i): self._button.SetLabel(self._labels[i]); 
self.Layout()
+
+class toggle_button(button):
+       """
+       Create a dual state button.
+       This button will alternate between True and False when clicked.
+       """
+       def __init__(self, true_label='On (click to stop)', false_label='Off 
(click to start)', **kwargs):
+               button.__init__(self, choices=[True, False], 
labels=[true_label, false_label], **kwargs)
+
+class single_button(toggle_button):
+       """
+       Create a single state button.
+       This button will callback() when clicked.
+       For use when state holding is not important.
+       """
+       def __init__(self, label='click for callback', **kwargs):
+               toggle_button.__init__(self, true_label=label, 
false_label=label, value=True, **kwargs)
+
+########################################################################
+# Radio Buttons Chooser Form
+########################################################################
+class radio_buttons(_chooser_base):
+       """
+       Create a radio button form.
+       @param parent the parent widget
+       @param sizer add this widget to sizer if provided (optional)
+       @param proportion the proportion when added to the sizer (default=0)
+       @param ps the pubsub object (optional)
+       @param key the pubsub key (optional)
+       @param value the default value (optional)
+       @param choices list of possible values
+       @param labels list of labels for each choice (default=choices)
+       @param major_dimension the number of rows/cols (default=auto)
+       @param label title label for this widget (optional)
+       @param style useful style args: wx.RA_HORIZONTAL, wx.RA_VERTICAL, 
wx.NO_BORDER (default=wx.RA_HORIZONTAL)
+       """
+       def __init__(self, style=wx.RA_HORIZONTAL, label='', major_dimension=0, 
**kwargs):
+               _chooser_base.__init__(self, **kwargs)
+               #create radio buttons
+               self._radio_buttons = wx.RadioBox(self._parent, 
choices=self._labels, style=style, label=label, majorDimension=major_dimension)
+               self._add_widget(self._radio_buttons)
+               self._radio_buttons.Bind(wx.EVT_RADIOBOX, self._handle)
+               self._init()
+
+       def _handle(self, event): self[INT_KEY] = 
self._radio_buttons.GetSelection()
+       def _update(self, i): self._radio_buttons.SetSelection(i)
+
+########################################################################
+# Notebook Chooser Form
+#  The notebook pages/tabs are for selecting between choices.
+#  A page must be added to the notebook for each choice.
+########################################################################
+class notebook(_chooser_base):
+       def __init__(self, **kwargs):
+               _chooser_base.__init__(self, **kwargs)
+               self._notebook = wx.Notebook(self._parent)
+               self._add_widget(self._notebook)
+               self._notebook.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self._handle)
+               self._index = 0
+
+       def add_page(self, page):
+               """
+               Add pages in order that the choices were presented.
+               """
+               assert self._index < len(self._choices)
+               self._notebook.AddPage(page, self._labels[self._index])
+               self._index += 1
+
+       #get at the real notebook object for adding pages and such
+       def get_notebook(self): return self._notebook
+
+       def _handle(self, event): self[INT_KEY] = self._notebook.GetSelection()
+       def _update(self, i): self._notebook.SetSelection(i)
+
+
+
+
+
+# ----------------------------------------------------------------
+# Stand-alone test application
+# ----------------------------------------------------------------
+
+import wx
+from gnuradio.wxgui import gui
+
+class app_gui (object):
+    def __init__(self, frame, panel, vbox, top_block, options, args):
+        
+        def callback(v): print v
+       
+        radio_buttons(
+            sizer=vbox,
+            parent=panel,
+            choices=[2, 4, 8, 16],
+            labels=['two', 'four', 'eight', 'sixteen'],
+            value=4,
+            style=wx.RA_HORIZONTAL,
+            label='test radio long string',
+            callback=callback,
+            #major_dimension = 2,
+        )
+        
+        radio_buttons(
+            sizer=vbox,
+            parent=panel,
+            choices=[2, 4, 8, 16],
+            labels=['two', 'four', 'eight', 'sixteen'],
+            value=4,
+            style=wx.RA_VERTICAL,
+            label='test radio long string',
+            callback=callback,
+            #major_dimension = 2,
+        )
+        
+        radio_buttons(
+            sizer=vbox,
+            parent=panel,
+            choices=[2, 4, 8, 16],
+            labels=['two', 'four', 'eight', 'sixteen'],
+            value=4,
+            style=wx.RA_VERTICAL | wx.NO_BORDER,
+            callback=callback,
+            #major_dimension = 2,
+        )
+        
+        button(
+            sizer=vbox,
+            parent=panel,
+            choices=[2, 4, 8, 16],
+            labels=['two', 'four', 'eight', 'sixteen'],
+            value=2,
+            label='button value',
+            callback=callback,
+            #width=100,
+        )
+        
+        
+        drop_down(
+            sizer=vbox,
+            parent=panel,
+            choices=[2, 4, 8, 16],
+            value=2,
+            label='Choose One',
+            callback=callback,
+        )
+        check_box(
+            sizer=vbox,
+            parent=panel,
+            value=False,
+            label='check me',
+            callback=callback,
+        )
+        text_box(
+            sizer=vbox,
+            parent=panel,
+            value=3,
+            label='text box',
+            callback=callback,
+            width=200,
+        )
+        
+        static_text(
+            sizer=vbox,
+            parent=panel,
+            value='bob',
+            label='static text',
+            width=-1,
+            bold=True,
+        )
+        
+        slider(
+            sizer=vbox,
+            parent=panel,
+            value=12,
+            label='slider',
+            callback=callback,
+        )
+        
+        log_slider(
+            sizer=vbox,
+            parent=panel,
+            value=12,
+            label='slider',
+            callback=callback,
+        )
+        
+        slider(
+            sizer=vbox,
+            parent=panel,
+            value=12,
+            label='slider',
+            callback=callback,
+            style=wx.SL_VERTICAL,
+            length=30,
+        )
+               
+        toggle_button(
+            sizer=vbox,
+            parent=panel,
+            value=True,
+            label='toggle it',
+            callback=callback,
+        )
+        
+        single_button(
+            sizer=vbox,
+            parent=panel,
+            label='sig test',
+            callback=callback,
+        )
+
+if __name__ == "__main__":
+    try:
+
+        # Create the GUI application
+        app = gui.app(
+                      gui=app_gui,                     # User interface class
+                      title="Test Forms",  # Top window title
+                      )
+
+        # And run it
+        app.MainLoop()
+
+    except RuntimeError, e:
+        print e
+        sys.exit(1)


Property changes on: gnuradio/branches/features/experimental-gui/forms/forms.py
___________________________________________________________________
Added: svn:mergeinfo
   + 





reply via email to

[Prev in Thread] Current Thread [Next in Thread]