Hello All:
I am currently working on a project to create an FEM model for school.
I was thinking about using wxPython to gather the 12 input variables
from the user, then, after pressing the "Run" button, the GUI would
close, and the 12 input variables would then be available for the rest
of the program.
So far, what I have been able to do is mostly a reverse engineering
job to get the frame to look right and return the text variables to a
"messageBox", but how do I get it to just return variables?
Any help on how to get the program to output the data back to the main
python program and close when I press submit? My apologies if this is
something of a simple question, but I have only started in on wxPython
about a week ago, and Python this term.
Some things I'm thinking about are as follows:
(1)
I have read about a "redirect" that could be used to send the values
to a file. But, then I would have to open the file and read in the
data from there. This seems crude and lacking elegance.
(2)
Perhaps have the GUI still return the variables to the "messageBox", but
when I close the messageBox have the program close. That is, have the
"OnSubmit" function (see below code) collect the input and verify with the user
as well as return the variables to the main program. The idea then would be that
upon closing the messageBox, the GUI would close and the variables have
already been passed to the main program.
Still, though, I do not know how to "return" the variables....
The codes I am using are below. A good eye will notice the not-so-subtle hack
of Robin Dunn's realworld_print.py example from wxPython in Action with an
added messageBox
Any ideas you may have for me to try out are greatly appreciated.
Cheers,
t.
*test_femgui.py*
···
--------------------------------------------------
#!/usr/bin/env python
import femGUI
# Initialize GUI and retrieve user inputs
app = femGUI.MyApp(False)
dlg = femGUI.FemInput()
dlg.Destroy()
app.MainLoop()
# Have the GUI close and return the user inputs
# Then do something with inputs here....
*femGUI.py*
--------------------------------------------------
import wx
class FemInput(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1, "Options Input Interface")
panel = wx.Panel(self)
# First create the controls
# Title
topLbl = wx.StaticText(panel, -1, "FEM 2D Basket Put
Option",size=(420,-1))
topLbl.SetFont(wx.Font(18, wx.SWISS, wx.NORMAL, wx.BOLD))
# S1 lower and upper bounds for grid
s1label = wx.StaticText(panel, -1, "S1 Low , S2 Low: ",size=(220,-1))
self.s1lower = wx.TextCtrl(panel, -1, "", size=(100,-1));
self.s2lower = wx.TextCtrl(panel, -1, "", size=(100,-1));
# S2 lower and upper bounds for grid
s2label = wx.StaticText(panel, -1, "S1 High, S2 High: ", size=(220,-1))
self.s1upper = wx.TextCtrl(panel, -1, "", size=(100,-1));
self.s2upper = wx.TextCtrl(panel, -1, "", size=(100,-1));
# S1 and S2 volatility
vlabel = wx.StaticText(panel, -1, "S1 Volatility, S2
Volatility: ", size=(220,-1))
self.v1vol = wx.TextCtrl(panel, -1, "", size=(100,-1));
self.v2vol = wx.TextCtrl(panel, -1, "", size=(100,-1));
# Risk free rate and correlation
prlabel = wx.StaticText(panel, -1, "Interest Rate,Correlation:
", size=(220,-1))
self.risk = wx.TextCtrl(panel, -1, "", size=(100,-1));
self.corr = wx.TextCtrl(panel, -1, "", size=(100,-1));
# Strike and Exercise Date
kTlabel = wx.StaticText(panel, -1, "Srike Price, Exercise
Date: ", size=(220,-1))
self.strike = wx.TextCtrl(panel, -1, "", size=(100,-1));
self.finalT = wx.TextCtrl(panel, -1, "", size=(100,-1));
# deltaT and deltaX
dTXlabel = wx.StaticText(panel, -1, "delta T, delta X: ",size=(220,-1))
self.deltaT = wx.TextCtrl(panel, -1, "", size=(100,-1));
self.deltaX = wx.TextCtrl(panel, -1, "", size=(100,-1));
# Execute program
runBtn = wx.Button(panel, -1, "Run")
self.Bind(wx.EVT_BUTTON, self.OnSubmit, runBtn)
# Now do the layout.
# mainSizer is the top-level one that manages everything
mainSizer = wx.BoxSizer(wx.VERTICAL)
mainSizer.Add(topLbl, 0, wx.ALL, 5)
mainSizer.Add(wx.StaticLine(panel), 0,
wx.EXPAND|wx.TOP|wx.BOTTOM, 5)
# femSizer is a grid that holds all of the address info
femSizer = wx.FlexGridSizer(cols=2, hgap=5, vgap=5)
femSizer.AddGrowableCol(1)
# S1 and S2 LOWER label
femSizer.Add(s1label, 0,
wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
# the lower and upper S1 bounds are in a sub-sizer
s1Sizer = wx.BoxSizer(wx.HORIZONTAL)
s1Sizer.Add(self.s1lower, 1)
s1Sizer.Add((10,10)) # some empty space
s1Sizer.Add(self.s2lower, 1, wx.LEFT|wx.RIGHT, 5)
femSizer.Add(s1Sizer, 1, wx.EXPAND)
# S1 and S2 HIGH label
femSizer.Add(s2label, 0,
wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
# the lower and upper S1 bounds are in a sub-sizer
s2Sizer = wx.BoxSizer(wx.HORIZONTAL)
s2Sizer.Add(self.s1upper, 1)
s2Sizer.Add((10,10)) # some empty space
s2Sizer.Add(self.s2upper, 1, wx.LEFT|wx.RIGHT, 5)
femSizer.Add(s2Sizer, 1, wx.EXPAND)
# Volatility label
femSizer.Add(vlabel, 0,
wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
# the lower and upper S1 bounds are in a sub-sizer
volSizer = wx.BoxSizer(wx.HORIZONTAL)
volSizer.Add(self.v1vol, 1)
volSizer.Add((10,10)) # some empty space
volSizer.Add(self.v2vol, 1, wx.LEFT|wx.RIGHT, 5)
femSizer.Add(volSizer, 1, wx.EXPAND)
# Risk free Rate and corelation
femSizer.Add(prlabel, 0,
wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
# the lower and upper S1 bounds are in a sub-sizer
rcSizer = wx.BoxSizer(wx.HORIZONTAL)
rcSizer.Add(self.risk, 1)
rcSizer.Add((10,10)) # some empty space
rcSizer.Add(self.corr, 1, wx.LEFT|wx.RIGHT, 5)
femSizer.Add(rcSizer, 1, wx.EXPAND)
# Strike and Exercise Date
femSizer.Add(kTlabel, 0,
wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
# the lower and upper S1 bounds are in a sub-sizer
ktSizer = wx.BoxSizer(wx.HORIZONTAL)
ktSizer.Add(self.strike, 1)
ktSizer.Add((10,10)) # some empty space
ktSizer.Add(self.finalT, 1, wx.LEFT|wx.RIGHT, 5)
femSizer.Add(ktSizer, 1, wx.EXPAND)
# deltaT and deltaX
femSizer.Add(dTXlabel, 0,
wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
# the lower and upper S1 bounds are in a sub-sizer
dtxSizer = wx.BoxSizer(wx.HORIZONTAL)
dtxSizer.Add(self.deltaT, 1)
dtxSizer.Add((10,10)) # some empty space
dtxSizer.Add(self.deltaX, 1, wx.LEFT|wx.RIGHT, 5)
femSizer.Add(dtxSizer, 1, wx.EXPAND)
# now add the femSizer to the mainSizer
mainSizer.Add(femSizer, 0, wx.EXPAND|wx.ALL, 10)
# The buttons sizer will put them in a row with resizeable
# gaps between and on either side of the buttons
btnSizer = wx.BoxSizer(wx.HORIZONTAL)
btnSizer.Add((10,10)) # some empty space
btnSizer.Add(runBtn)
btnSizer.Add((10,10)) # some empty space
mainSizer.Add(btnSizer, 0, wx.EXPAND|wx.BOTTOM, 10)
panel.SetSizer(mainSizer)
# Fit the frame to the needs of the sizer. The frame will
# automatically resize the panel as needed. Also prevent the
# frame from getting smaller than this size.
mainSizer.Fit(self)
mainSizer.SetSizeHints(self)
def OnSubmit(self, evt):
s1low = self.s1lower.GetValue()
s2low = self.s2lower.GetValue()
s1high = self.s1upper.GetValue()
s2high = self.s2upper.GetValue()
s1vol = self.v1vol.GetValue()
s2vol = self.v2vol.GetValue()
irate = self.risk.GetValue()
pcorr = self.corr.GetValue()
kprice = self.strike.GetValue()
totalT = self.finalT.GetValue()
delT = self.deltaT.GetValue()
delX = self.deltaX.GetValue()
wx.MessageBox('You chose: \n %s \n %s \n %s \n %s \
\n %s \n %s \n %s' % (s1low,s2low,s1high,s2high,s1vol,s2vol,irate))
# I want to do something like this below....
# return s1low,s2low,s1high,s2high,s1vol,s2vol,irate
class MyApp(wx.App):
def OnInit(self):
frame = FemInput()
self.SetTopWindow(frame)
frame.Show()
return True
# Needed if called as a module
if __name__ == '__main__':
app = MyApp(False)
app.MainLoop()
--
Tyler Joseph Hayes
GPG Key ID# 0x3AE05130