lamba
lamba

Reputation: 1651

wxpython event handling between multiple classes

I have two classes in wxpython, a wx.Frame class and a wx.Dialog (calendar dialog) class

My calendar dialog looks like this:

class Calendar(wx.Dialog):
    def __init__(self, parent, id, title):
        wx.Dialog.__init__(self, parent, id, title)

        vbox = wx.BoxSizer(wx.VERTICAL)

        self.calend = cal.CalendarCtrl(self, -1, wx.DateTime_Now(),
            style = cal.CAL_SHOW_HOLIDAYS|cal.CAL_SEQUENTIAL_MONTH_SELECTION)
        vbox.Add(self.calend, 0, wx.EXPAND | wx.ALL, 20)

        vbox.Add((-1, 20))

        hbox2 = wx.BoxSizer(wx.HORIZONTAL)
        btn = wx.Button(self, -1, 'Ok')
        cancelBtn = wx.Button(self, -1, 'Cancel')
        hbox2.Add(btn, 1)
        hbox2.Add(cancelBtn, 1)
        vbox.Add(hbox2, 0, wx.ALIGN_CENTER | wx.TOP | wx.BOTTOM, 20)

        btn.Bind(wx.EVT_BUTTON, self.okClicked)
        cancelBtn.Bind(wx.EVT_BUTTON, self.OnQuit)

        self.SetSizerAndFit(vbox)

        self.Show(True)
        self.Centre()


    def okClicked(self, event):
        date = self.calend.GetDate()
        print date
        return date

And I call the calendar dialog from my frame class like so

def calClick1(self, event):
    calObj = Calendar(None, -1, 'test cal')
    calObj.ShowModal()
    #here i want to set the returned date to a wx.TextCtrl

How do I set the value of a TextCtrl box in my wx.Frame class to the returned date in the calendar dialog class?

Upvotes: 0

Views: 1570

Answers (2)

AWainb
AWainb

Reputation: 868

As demonstrated in the wxPython demo, when you call ShowModal() it should be used within an if statement:

if calObj.ShowModal() == wx.ID_OK:

Now if you were to change:

def okClicked(self, event):
    date = self.calend.GetDate()
    print date
    return date

To:

def okClicked(self, event):
    self.date = self.calend.GetDate()
    print self.date
    return self.date

Than your date variable will be global to the class and you can access it through calObj from within the frame, like: calObj.date

than you could do something like this which will allow you to make the changes to the frame's TextCtrl after the Dialog has been closed, instead of calling back to the parent: (not that there is anything wrong with that of course! ;)

Untested, but the below should do the trick for you:

# Dialog
class Calendar(wx.Dialog):
    def __init__(self, parent, id, title):
        wx.Dialog.__init__(self, parent, id, title)

        self.date = wx.DateTime_Now() #create global variable 'self.date'

        vbox = wx.BoxSizer(wx.VERTICAL)
        self.calend = cal.CalendarCtrl(self, -1, self.date, #from wx.DateTime_Now()
            style = cal.CAL_SHOW_HOLIDAYS|cal.CAL_SEQUENTIAL_MONTH_SELECTION)
        vbox.Add(self.calend, 0, wx.EXPAND | wx.ALL, 20)

        vbox.Add((-1, 20))

        hbox2 = wx.BoxSizer(wx.HORIZONTAL)
        btn = wx.Button(self, wx.ID_OK, 'Ok') #changed id to wx.ID_OK
        cancelBtn = wx.Button(self, wx.ID_CANCEL, 'Cancel') #id to wx.ID_CANCEL
        hbox2.Add(btn, 1)
        hbox2.Add(cancelBtn, 1)
        vbox.Add(hbox2, 0, wx.ALIGN_CENTER | wx.TOP | wx.BOTTOM, 20)

        btn.Bind(wx.EVT_BUTTON, self.okClicked)
        cancelBtn.Bind(wx.EVT_BUTTON, self.OnQuit)

        self.SetSizerAndFit(vbox)

        self.Show(True)
        self.Centre()


    def okClicked(self, event):
        self.date = self.calend.GetDate() #set global value 'date' to selection
        print self.date
        return self.date


#Frame function
def calClick1(self, event):
    calObj = Calendar(None, -1, 'test cal')
    #if you clicked ok, continue...
    if calObj.ShowModal() == wx.ID_OK:
        # Set the TextCtrl by calling the global variable 'calObj.date'
        self.MyTextCtrl.SetValue(calObj.date)

Upvotes: 1

marb
marb

Reputation: 111

In calClick1 make instance of Calendar with self as parent:

calObj = Calendar(self, -1, 'test cal')

In Calendar class add something like: self.parent = parent after wx.Dialog.__init__(...). Now you can access attributes of frame in calendar. Example:

If you have in Frame class something like:

self.txt = wx.TextCtrl(self, -1, 'sample txt')

You can change it in method okClicked of class Calendar:

self.parent.txt.SetValue('some new string value')

Upvotes: 2

Related Questions