从wxPython事件处理程序中调用函数

时间:2012-05-12 22:03:26

标签: python wxpython

我正在努力寻找一种在wxPython事件处理函数中使用函数的方法。假设我有一个按钮,当单击它时,它使用事件处理程序运行一个名为OnRun的函数。但是,用户忘记在OnRun按钮之前单击RadionButton,我想弹出MessageDialog告诉他们忘记了一步。我将多次重复使用这个MessageDialog,因此,而不是复制/粘贴相同的代码,我想在函数中只有这个MessageDialog,如果用户忘记检查RadioButton,则调用此MessageDialog函数。

如果这不是事件处理程序中使用的函数,我知道我可以简单地将函数作为参数,但我没有看到我可以用这些方法做到这一点。任何帮助在这里将不胜感激。

3 个答案:

答案 0 :(得分:1)

即使答案看起来过于直接,我也会对此进行抨击。我会在封闭框架中设置一个属性,用于标记是否单击了单选按钮。然后在调用OnRun时检查该属性。如果它处于错误状态,请调用MessageDialog并中止/暂停/修改OnRun

编辑这就是我的意思,这是一个带有两个按钮的简单示例,除非单击用户协议,否则这两个按钮都不会导致进一步操作。

import wx

class ButtonFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, -1, 'Button Example', 
                          size=(300, 100))
        panel = wx.Panel(self, -1)
        self.radio = wx.RadioButton(panel, -1, "Accept user agreement", pos=(50, 10))
        self.button = wx.Button(panel, -1, "Run", pos=(50, 30))
        self.Bind(wx.EVT_BUTTON, self.OnRun, self.button)
        self.button.SetDefault()
        self.btn2 = wx.Button(panel, -1, "Walk", pos=(150, 30))
        self.Bind(wx.EVT_BUTTON, self.OnWalk, self.btn2)

    def OnRun(self, event):
        if not self.CheckRadio():
            return
        self.button.SetLabel("Running")

    def OnWalk(self, event):
        if not self.CheckRadio():
            return
        self.btn2.SetLabel("Walking")

    def CheckRadio(self):
        accepted = self.radio.GetValue()
        if not accepted:
            dlg = wx.MessageDialog(None, 'First accept the user agreement',
                                  'MessageDialog', wx.OK | wx.ICON_QUESTION)
            result = dlg.ShowModal() # result not used in this demo
            dlg.Destroy()
            return False
        else:
            return True

if __name__ == '__main__':
    app = wx.PySimpleApp()
    frame = ButtonFrame()
    frame.Show()
    app.MainLoop()

代码改编自wxPython in Action的清单7.11。如果你还没有解决这个问题,我希望这会有所帮助。

答案 1 :(得分:1)

以下代码显示了如何创建一个可以重复使用的小方法来显示自定义对话框并告诉用户他们需要接受协议。当然,您可以更改条件以执行任何操作。你可以改变“showMsg”方法,这样只需稍加调整就可以改变图标。

import wx

########################################################################
class TestFrame(wx.Frame):
    """"""

    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        wx.Frame.__init__(self, None, title="Test")

        panel = wx.Panel(self)
        self.radios = wx.RadioBox(panel, label="Choices",
                                  choices = ["None", "Accept", "Reject"])

        button = wx.Button(panel, label="Run")
        button.Bind(wx.EVT_BUTTON, self.onBtn)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.radios, 0, wx.ALL, 5)
        sizer.Add(button, 0, wx.ALL, 5)
        panel.SetSizer(sizer)

    #----------------------------------------------------------------------
    def onBtn(self, event):
        """"""
        btn = event.GetEventObject()
        btn.SetLabel("Running")
        radio_value = self.radios.GetStringSelection()
        if radio_value == "None":
            self.showMsg("Error", "Please Choose 'Accept' or 'Reject'!")
        elif radio_value == "Accept":
            self.showMsg("Message", "Thank you for accepting!")
        else:
            self.showMsg("Message", "We're sorry, but you cannot continue the install")

    #----------------------------------------------------------------------
    def showMsg(self, title, msg):
        """"""
        dlg = wx.MessageDialog(None, msg, title, wx.OK | wx.ICON_QUESTION)
        dlg.ShowModal()
        dlg.Destroy()



if __name__ == "__main__":
    app = wx.App(False)
    frame = TestFrame()
    frame.Show()
    app.MainLoop()

答案 2 :(得分:0)

您可以创建自己的MessageDialog(继承),也可以使用functools.partial / lambda将其他参数传递给事件处理程序:

self.Bind(wx.MY_EVENT, lambda evt: self.OnEventX(evt, handler=foo), id=12)