I am trying to use wx.Choice component to archieve a simple application.
The idea is, a number of items are listed in the wx.Choice, and each of them will trigger an unique function.
My first version of code was:
class MainFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, 0, 'wxPython pull-down choice', size = (400, 300))
panel_select_model= wx.Panel(self, -1)
model_list = ['Test_A', 'Test_B']
self._model_type = None
self._stat_tex = wx.StaticText(panel_select_model, 1, "Select Model Type:", (15, 20))
self._droplist = wx.Choice(panel_select_model, 2, (150, 18), choices = model_list)
""" Bind A Panel """
self._droplist.SetSelection(0)
self._droplist.Bind(wx.EVT_CHOICE, self.Test_A_click)
But it turns out that the two items in the dropdown list will trigger the same function (I expect that the Test_A will trigger that function and Test_B simply do nothing). So I try to bind Test_B to another method Test_B_click
class MainFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, 0, 'wxPython pull-down choice', size = (400, 300))
panel_select_model= wx.Panel(self, -1)
model_list = ['Test_A', 'Test_B']
self._model_type = None
self._stat_tex = wx.StaticText(panel_select_model, 1, "Select Model Type:", (15, 20))
self._droplist = wx.Choice(panel_select_model, 2, (150, 18), choices = model_list)
""" Bind A Panel """
self._droplist.SetSelection(0)
self._droplist.Bind(wx.EVT_CHOICE, self.Test_A_click)
""" Bind B Panel """
self._droplist.SetSelection(1)
self._droplist.Bind(wx.EVT_CHOICE, self.Test_B_click)
The above code display a main frame, a drop list in it and two items in the drop list. However, when I click either of the two items, no function is triggered anymore.
So, how can I archieve my goal: Bind different functions to each of the items in a wx.Choice component, and make them trigger functions correctly.
Thanks.
Your methodology is probably the most common way to do what you want and it's pretty easy to tell what's going on as well. However if you do this with a little dash of meta-programming that might be a little cleaner if you set it up correctly:
import wx
########################################################################
class MyFrame(wx.Frame):
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
wx.Frame.__init__(self, None, title="Callbacks")
panel = wx.Panel(self)
self.choice = wx.Choice(panel, choices=["test_A", "test_B"])
self.choice.Bind(wx.EVT_CHOICE, self.onChoice)
self.Show()
#----------------------------------------------------------------------
def onChoice(self, event):
choice = self.choice.GetStringSelection()
method = getattr(self, "on_%s" % choice)
method()
#----------------------------------------------------------------------
def on_test_A(self):
print "You chose test_A!"
#----------------------------------------------------------------------
def on_test_B(self):
print "You chose test_B!"
#----------------------------------------------------------------------
if __name__ == "__main__":
app = wx.App(False)
frame = MyFrame()
app.MainLoop()
Here we use Python's getattr function to determine which method to actually call. This allows us to skip the use of the if statement, but assumes that we have all the methods set up for all the choices in the control.
I am coming back to ask my own question. I don't think this is the perfect solution, but it managed my way out.
Here is the code:
class MainFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, 0, 'wxPython pull-down choice', size = (400, 300))
panel_select_model= wx.Panel(self, -1)
model_list = ['Test_A', 'Test_B']
self._model_type = None
self._stat_tex = wx.StaticText(panel_select_model, 1, "Select Model Type:", (15, 20))
self._droplist = wx.Choice(panel_select_model, 2, (150, 18), choices = model_list)
""" Bind A Panel """
self._droplist.SetSelection(0)
self._droplist.Bind(wx.EVT_CHOICE, self.choice_click)
""" Bind B Panel """
self._droplist.SetSelection(1)
self._droplist.Bind(wx.EVT_CHOICE, self.choice_click)
def choice_click(self, event):
if self._droplist.GetStringSelection() == "Test_A":
self.Test_A__click()
elif self._droplist.GetStringSelection() == "Test_B":
self.Test_B_click()
In above code. I put another layer between the wx.Choice component and the functions that I would like to trigger. Once we have a match, its corresponding function will be triggered.
I am afraid this is not an effective way. So I would be extremely appreciate if anyone can bring up a good solution. Thanks a lot.
Related
I am currently making a UI in python using wx. I am trying to have multiple tabs active at the same time, but at the same time I am trying to keep either a list or int value active and showing in the bottom right corner on any tab at all times. Unfortunately I seem to have run into a road block. When I run the code below I get the error:
i = parent.GetString(Points.a)
TypeError: CommandEvent.GetString(): too many arguments
Honestly I am only a year into coding practice and I don't really know what this error means. If possible, could someone please explain it to me and possible give me some tips on how to solve the issue?
Thanks in advance.
import wx
class Points:
c = 14
a = [14]
b = "{}\n" .format(a)
class MOC(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
self.poi = wx.StaticText(self, label=Points.b, pos=(400, 400))
select = wx.Button(self, wx.ID_ANY, '+1', size=(90, 30))
select.Bind(wx.EVT_BUTTON, self.add)
def add(self, parent):
i = parent.GetString(Points.a)
Points.a.remove(Points.c)
Points.c += 1
Points.a.append(Points.c)
self.poi.SetLabel(i)
class TOS(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
wx.StaticText(self, label=Points.b, pos=(400, 400))
class UIFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, size = (500,500), title = "Mind")
p = wx.Panel(self)
nb = wx.Notebook(p)
page1 = MOC(nb)
page2 = TOS(nb)
nb.AddPage(page1, "Means")
nb.AddPage(page2, "Types")
sizer = wx.BoxSizer()
sizer.Add(nb, 1, wx.EXPAND)
p.SetSizer(sizer)
if __name__ == "__main__":
app = wx.App()
UIFrame().Show()
app.MainLoop()
In the line i = parent.GetString(Points.a) you are passing the argument Points.a but GetString has no arguments because it is used to get the string from an item i.e. self.Item.GetString().
Points.a is not a wx defined item, it is in fact a python list, to access that you should change the offending line above with
i = str(Points.a[0]) or
i = Points.a[0] or
i = Points.a or
i = str(Points.a) depending on your requirements.
Depending on which access method you choose, you may have to alter the
self.poi.SetLabel(i) as well, as i could be a list or an int rather than the required str
Running with the first option works without further changes
I am using Python WX to make a large GUI containing maybe 100 CheckBoxes. I want to read the value of each checkbox and append these values to a list. I can do this with 100 lines of code but prefer to use a loop. In the loop, how can I identify or select the specific checkbox I want to get the value from?
self.Box1 = wx.CheckBox(self.panel, id = 1, label='first box', pos=(10, 25), size=(30,22))
self.Box2 = wx.CheckBox(self.panel, id = 2, label='second box', pos=(20, 25), size=(30,22))
.
.
.
self.Box100 = wx.CheckBox(self.panel, id = 100, label='100th box', pos=(100, 25), size=(30,22))
Looking for something like:
MyList = []
for N in range (1, 101):
MyList.append(self.Box + N.Value)
The more generic question here is "how to select an object name in a loop"
I have searched all day with no luck. I am not a programming expert and hope this is worthy of someone's answer.
Rather than having 100 almost-identical lines of code, which is error-prone, inefficient and unattractive, actually build the CheckBoxes in a loop and hold them in a list:
self.boxes = []
for i in range(1, 101):
self.boxes.append(wx.CheckBox(self.panel, id=i,
label="Box {0}".format(i)
pos=(10, 25), size=(30,22)))
Then getting all of the values is similarly simple:
for i, box in enumerate(self.boxes, 1):
...
as is accessing a single one:
box = self.boxes[i-1]
If you really want "first", "second", "100th" write a helper function to process i into a string representation.
I personally like to use widget names. For example:
import wx
########################################################################
class MyPanel(wx.Panel):
""""""
#----------------------------------------------------------------------
def __init__(self, parent):
"""Constructor"""
wx.Panel.__init__(self, parent)
self.sizer = wx.BoxSizer(wx.VERTICAL)
for i in range(5):
txt = "Checkbox #%s" % i
chk = wx.CheckBox(self, label=txt, name=txt)
self.sizer.Add(chk, 0, wx.ALL|wx.CENTER, 5)
button = wx.Button(self, label="Get check")
button.Bind(wx.EVT_BUTTON, self.onButton)
self.sizer.Add(button, 0, wx.ALL|wx.CENTER, 5)
self.SetSizer(self.sizer)
#----------------------------------------------------------------------
def onButton(self, event):
""""""
widget = self.FindWindowByName("Checkbox #0")
print widget
print widget.GetValue()
########################################################################
class MyFrame(wx.Frame):
""""""
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
wx.Frame.__init__(self, None, title="Checkboxes")
panel = MyPanel(self)
self.Show()
#----------------------------------------------------------------------
if __name__ == "__main__":
app = wx.App(False)
frame = MyFrame()
app.MainLoop()
This code will create a set of 5 wx.Checkboxes that each have a unique name. Then you can look them up by name using wx.FindWindowByName.
You could also create a dictionary using the names as the keys and the values as the CheckBox widgets which gives the advantage of being a faster lookup.
One of the columns in my ObjectListView contains data that is too long to display completely, so it's automatically truncated. I would like a way to display all the data in the cell. I've already implemented the suggestion in this tutorial, but I'm not very happy with the result because the tooltip is for the entire list, not just that list item. Ideally, I'd like to have exactly what's pictured in the first image of this other question.
That post mentions that the expansion-on-hover behavior happens automatically, but I don't see any way of recreating that behavior. Perhaps it only happens on Windows? I'm running on GTK.
You could always implement an on right click pop-up window that you can populate with whatever you would like - see the wxPython Demo for Pop-up windows as a starting point.
Alternatively you could switch from ObjectListView to wx.lib.agw.UltimateListCtrl or DataViewControl - both of these seem to support tooltips that are aware of which row and column you are hovering over.
I messed around with the code in my tutorial using the answer you had mentioned and came up with the following:
import wx
from ObjectListView import ObjectListView, ColumnDefn
########################################################################
class Book(object):
"""
Model of the Book object
Contains the following attributes:
'ISBN', 'Author', 'Manufacturer', 'Title'
"""
#----------------------------------------------------------------------
def __init__(self, title, author, isbn, mfg):
self.isbn = isbn
self.author = author
self.mfg = mfg
self.title = title
########################################################################
class MainPanel(wx.Panel):
#----------------------------------------------------------------------
def __init__(self, parent):
wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
self.products = [Book("wxPython in Action", "Robin Dunn",
"1932394621", "Manning"),
Book("Hello World", "Warren and Carter Sande",
"1933988495", "Manning")
]
self.dataOlv = ObjectListView(self, wx.ID_ANY,
style=wx.LC_REPORT|wx.SUNKEN_BORDER)
self.dataOlv.Bind(wx.EVT_MOTION, self.updateTooltip)
self.setBooks()
# Allow the cell values to be edited when double-clicked
self.dataOlv.cellEditMode = ObjectListView.CELLEDIT_SINGLECLICK
# create an update button
updateBtn = wx.Button(self, wx.ID_ANY, "Update OLV")
updateBtn.Bind(wx.EVT_BUTTON, self.updateControl)
# Create some sizers
mainSizer = wx.BoxSizer(wx.VERTICAL)
mainSizer.Add(self.dataOlv, 1, wx.ALL|wx.EXPAND, 5)
mainSizer.Add(updateBtn, 0, wx.ALL|wx.CENTER, 5)
self.SetSizer(mainSizer)
#----------------------------------------------------------------------
def updateControl(self, event):
"""
Update the control
"""
print "updating..."
#product_dict = [{"title":"Core Python Programming", "author":"Wesley Chun",
#"isbn":"0132269937", "mfg":"Prentice Hall"},
#{"title":"Python Programming for the Absolute Beginner",
#"author":"Michael Dawson", "isbn":"1598631128",
#"mfg":"Course Technology"},
#{"title":"Learning Python", "author":"Mark Lutz",
#"isbn":"0596513984", "mfg":"O'Reilly"}
#]
product_list = [Book("Core Python Programming", "Wesley Chun",
"0132269937", "Prentice Hall"),
Book("Python Programming for the Absolute Beginner",
"Michael Dawson", "1598631128", "Course Technology"),
Book("Learning Python", "Mark Lutz", "0596513984",
"O'Reilly")
]
data = self.products + product_list
self.dataOlv.SetObjects(data)
#----------------------------------------------------------------------
def setBooks(self, data=None):
"""
Sets the book data for the OLV object
"""
self.dataOlv.SetColumns([
ColumnDefn("Title", "left", 220, "title"),
ColumnDefn("Author", "left", 200, "author"),
ColumnDefn("ISBN", "right", 100, "isbn"),
ColumnDefn("Mfg", "left", 180, "mfg")
])
self.dataOlv.SetObjects(self.products)
#----------------------------------------------------------------------
def updateTooltip(self, event):
"""
"""
pos = wx.GetMousePosition()
mouse_pos = self.dataOlv.ScreenToClient(pos)
item_index, flag = self.dataOlv.HitTest(mouse_pos)
print flag
if flag == wx.LIST_HITTEST_ONITEMLABEL:
msg = "%s is a good book!" % self.dataOlv.GetItemText(item_index)
self.dataOlv.SetToolTipString(msg)
else:
self.dataOlv.SetToolTipString("")
event.Skip()
########################################################################
class MainFrame(wx.Frame):
#----------------------------------------------------------------------
def __init__(self):
wx.Frame.__init__(self, parent=None, id=wx.ID_ANY,
title="ObjectListView Demo", size=(800,600))
panel = MainPanel(self)
#----------------------------------------------------------------------
def main():
"""
Run the demo
"""
app = wx.App(False)
frame = MainFrame()
frame.Show()
app.MainLoop()
#----------------------------------------------------------------------
if __name__ == "__main__":
main()
I also updated my tutorial to include the code above. Please note that the tooltip only updates when you mouse through the cells in the first column. I haven't found a good way around that.
If you run this code, you will get default values from a combo box on Panel One, but after changing the values on Panel 2, the values being called from the Panel 1 button do not reflect the change in values on Panel 2.
import wx
class PanelOne(wx.Panel):
def __init__(self, parent, id):
wx.Panel.__init__(self, parent, id)
self.button1 = wx.Button(self, -1, label="Panel 1 Test",
pos=wx.Point(100, 100))
self.button1.Bind(wx.EVT_BUTTON, self.button1Click, self.button1)
def button1Click(self,event):
p2=PanelTwo(self, 0)
print "Panel 1: %s" % p2.C1
print "Panel 1: %s" % p2.C2
class PanelTwo(wx.Panel):
def __init__(self, parent, id):
wx.Panel.__init__(self, parent, id)
# Default Declarations
self.C1 = List1[0]
self.C2 = List2[-1]
self.combo1 = wx.ComboBox(self, -1, value=List1[0], pos=wx.Point(100, 30),
size=wx.Size(100, 150), choices=List1, style = wx.CB_READONLY)
self.Bind(wx.EVT_COMBOBOX, self.EvtCmb1, self.combo1)
self.combo2 = wx.ComboBox(self, -1, value=List2[-1], pos=wx.Point(300, 30),
size=wx.Size(100, 150), choices=List2, style = wx.CB_READONLY)
self.Bind(wx.EVT_COMBOBOX, self.EvtCmb2, self.combo2)
self.button1 = wx.Button(self, -1, label="Panel 2 Test",
pos=wx.Point(100, 100))
self.button1.Bind(wx.EVT_BUTTON, self.button1Click, self.button1)
def button1Click(self,event):
print "Panel 2: %s" % self.C1
print "Panel 2: %s" % self.C2
def EvtCmb1(self, event):
combo1 = (event.GetString())
self.C1 = combo1
def EvtCmb2(self, event):
combo2 = (event.GetString())
self.C2 = combo2
class MainFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="Testing 123", size = (500, 400) )
p = wx.Panel(self)
nb = wx.Notebook(p)
panel1 = PanelOne(nb,-1)
panel2 = PanelTwo(nb,-1)
nb.AddPage(panel1, "Page One")
nb.AddPage(panel2, "Page Two")
sizer = wx.BoxSizer()
sizer.Add(nb, 1, wx.EXPAND)
p.SetSizer(sizer)
#Combo1
List1 = ['Apple', 'Banana']
#Combo2
List2 = ["1", "2", "3", "4"]
app = wx.App(redirect=False)
frame = MainFrame()
frame.Show(True)
app.MainLoop()
I find your code confusing, but I think I found the problem. Consider your PanelOne.button1Click() function:
def button1Click(self,event):
p2=PanelTwo(self, 0)
print "Panel 1: %s" % p2.C1
print "Panel 1: %s" % p2.C2
You're creating a new instance of PanelTwo every time, meaning it will always have the default values. Think of classes like makes and models of cars. I can have a Toyota Camry and you can have a Toyota Camry. They are the same type (class) of car, but they are seperate cars (different instances). Any change I make to my Camry obviously won't affect yours since they are different objects entirely. So following this analogy, everytime PanelOne.button1Click() is called, it buys a new Camry (creates a new instance); it doesn't get an already existing one. That new car comes fresh from the factory with all the default options regardless of how other owners modify their cars.
So basically, your panel1 instance and your panel2 instance aren't talking to each other at all, so panel1 can't know anything about the state of panel2. You have a few ways you can solve this. The easiest way is to pass panel2 as an init argument for panel1. Like this:
class PanelOne(wx.Panel):
def __init__(self, parent, id, p2):
wx.Panel.__init__(self, parent, id)
self.p2 = p2 #store panel2 so we can check it later
#do the rest of your setup
def button1Click(self,event):
print "Panel 1: %s" % self.p2.C1
print "Panel 1: %s" % self.p2.C2
class MainFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="Testing 123", size = (500, 400) )
panel2 = PanelTwo(nb,-1)
panel1 = PanelOne(nb,-1, panel2) #panel1 needs to be able to read panel2's settings
#do the rest of your setup
This still isn't a great solution. Generally, I'd try to come up with something using PubSub to pass the information between classes without causing a dependency (i.e. note how PanelOne can never exist wthout PanelTwo, even in your original code), but I think that's overly complicated for your purposes.
In the following code (inspired by this snippet), I use a single event handler buttonClick to change the title of the window. Currently, I need to evaluate if the Id of the event corresponds to the Id of the button. If I decide to add 50 buttons instead of 2, this method could become cumbersome. Is there a better way to do this?
import wx
class MyFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, wx.ID_ANY, 'wxBitmapButton',
pos=(300, 150), size=(300, 350))
self.panel1 = wx.Panel(self, -1)
self.button1 = wx.Button(self.panel1, id=-1,
pos=(10, 20), size = (20,20))
self.button1.Bind(wx.EVT_BUTTON, self.buttonClick)
self.button2 = wx.Button(self.panel1, id=-1,
pos=(40, 20), size = (20,20))
self.button2.Bind(wx.EVT_BUTTON, self.buttonClick)
self.Show(True)
def buttonClick(self,event):
if event.Id == self.button1.Id:
self.SetTitle("Button 1 clicked")
elif event.Id == self.button2.Id:
self.SetTitle("Button 2 clicked")
application = wx.PySimpleApp()
window = MyFrame()
application.MainLoop()
You could give the button a name, and then look at the name in the event handler.
When you make the button
b = wx.Button(self, 10, "Default Button", (20, 20))
b.myname = "default button"
self.Bind(wx.EVT_BUTTON, self.OnClick, b)
When the button is clicked:
def OnClick(self, event):
name = event.GetEventObject().myname
Take advantage of what you can do in a language like Python. You can pass extra arguments to your event callback function, like so.
import functools
def __init__(self):
# ...
for i in range(10):
name = 'Button %d' % i
button = wx.Button(parent, -1, name)
func = functools.partial(self.on_button, name=name)
button.Bind(wx.EVT_BUTTON, func)
# ...
def on_button(self, event, name):
print '%s clicked' % name
Of course, the arguments can be anything you want.
I recommend that you use different event handlers to handle events from each button. If there is a lot of commonality, you can combine that into a function which returns a function with the specific behavior you want, for instance:
def goingTo(self, where):
def goingToHandler(event):
self.SetTitle("I'm going to " + where)
return goingToHandler
def __init__(self):
buttonA.Bind(wx.EVT_BUTTON, self.goingTo("work"))
# clicking will say "I'm going to work"
buttonB.Bind(wx.EVT_BUTTON, self.goingTo("home"))
# clicking will say "I'm going to home"
Keep a dict with keys that are the .Id of the buttons and values that are the button names or whatever, so instead of a long if/elif chain you do a single dict lookup in buttonClick.
Code snippets: in __init__, add creation and update of the dict:
self.panel1 = wx.Panel(self, -1)
self.thebuttons = dict()
self.button1 = wx.Button(self.panel1, id=-1,
pos=(10, 20), size = (20,20))
self.thebuttons[self.button1.Id] = 'Button 1'
self.button1.Bind(wx.EVT_BUTTON, self.buttonClick)
and so on for 50 buttons (or whatever) [they might be better created in a loop, btw;-)].
So buttonClick becomes:
def buttonClick(self,event):
button_name = self.thebuttons.get(event.Id, '?No button?')
self.setTitle(button_name + ' clicked')
You could create a dictionary of buttons, and do the look based on the id ... something like this:
class MyFrame(wx.Frame):
def _add_button (self, *args):
btn = wx.Button (*args)
btn.Bind (wx.EVT_BUTTON, self.buttonClick)
self.buttons[btn.id] = btn
def __init__ (self):
self.button = dict ()
self._add_button (self.panel1, id=-1,
pos=(10, 20), size = (20,20))
self._add_button = (self.panel1, id=-1,
pos=(40, 20), size = (20,20))
self.Show (True)
def buttonClick(self,event):
self.SetTitle (self.buttons[event.Id].label)
I ran into a similar problem: I was generating buttons based on user-supplied data, and I needed the buttons to affect another class, so I needed to pass along information about the buttonclick. What I did was explicitly assign button IDs to each button I generated, then stored information about them in a dictionary to lookup later.
I would have thought there would be a prettier way to do this, constructing a custom event passing along more information, but all I've seen is the dictionary-lookup method. Also, I keep around a list of the buttons so I can erase all of them when needed.
Here's a slightly scrubbed code sample of something similar:
self.buttonDefs = {}
self.buttons = []
id_increment = 800
if (row, col) in self.items:
for ev in self.items[(row, col)]:
id_increment += 1
#### Populate a dict with the event information
self.buttonDefs[id_increment ] = (row, col, ev['user'])
####
tempBtn = wx.Button(self.sidebar, id_increment , "Choose",
(0,50+len(self.buttons)*40), (50,20) )
self.sidebar.Bind(wx.EVT_BUTTON, self.OnShiftClick, tempBtn)
self.buttons.append(tempBtn)
def OnShiftClick(self, evt):
### Lookup the information from the dict
row, col, user = self.buttonDefs[evt.GetId()]
self.WriteToCell(row, col, user)
self.DrawShiftPicker(row, col)
I needed to do the same thing to keep track of button-presses . I used a lambda function to bind to the event . That way I could pass in the entire button object to the event handler function to manipulate accordingly.
class PlatGridderTop(wx.Frame):
numbuttons = 0
buttonlist = []
def create_another_button(self, event): # wxGlade: PlateGridderTop.<event_handler>
buttoncreator_id = wx.ID_ANY
butonname = "button" + str(buttoncreator_id)
PlateGridderTop.numbuttons = PlateGridderTop.numbuttons + 1
thisbutton_number = PlateGridderTop.numbuttons
self.buttonname = wx.Button(self,buttoncreator_id ,"ChildButton %s" % thisbutton_number )
self.Bind(wx.EVT_BUTTON,lambda event, buttonpressed=self.buttonname: self.print_button_press(event,buttonpressed),self.buttonname)
self.buttonlist.append(self.buttonname)
self.__do_layout()
print "Clicked plate button %s" % butonname
event.Skip()
def print_button_press(self,event,clickerbutton):
"""Just a dummy method that responds to a button press"""
print "Clicked a created button named %s with wxpython ID %s" % (clickerbutton.GetLabel(),event.GetId())
Disclaimer : This is my first post to stackoverflow