wxpython 多类间事件处理

0 投票
2 回答
1550 浏览
提问于 2025-04-16 14:00

我在wxpython中有两个类,一个是wx.Frame类,另一个是wx.Dialog(日历对话框)类。

我的日历对话框长这样:

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

然后我从我的框架类中这样调用日历对话框:

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

我该怎么做才能把日历对话框中选的日期设置到我wx.Frame类里的一个文本框(TextCtrl)里呢?

2 个回答

2

在calClick1里,创建一个以自己为父级的日历实例:

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

在日历类中,添加类似于:self.parent = parent的内容,放在wx.Dialog.__init__(...)之后。这样,你就可以在日历中访问框架的属性了。举个例子:

如果你在框架类中有类似的内容:

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

你可以在日历类的okClicked方法中进行修改:

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

在wxPython的示例中,当你调用ShowModal()时,应该在一个if语句中使用它:

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

现在如果你把:

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

改成:

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

那么你的日期变量就会变成这个类的全局变量,你可以通过calObj在窗口中访问它,比如:calObj.date

这样你就可以做一些事情,让你在对话框关闭后修改窗口中的TextCtrl,而不是回到父窗口去做这些事情:(当然,这样做没有什么问题!;)

虽然没有测试过,但下面的代码应该能帮到你:

# 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)

撰写回答