2

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

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

4

3 回答 3

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 。我希望这会有所帮助,如果您在过去的时间里还没有解决这个问题。

于 2012-05-12T22:23:19.400 回答
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()
于 2012-05-14T14:34:24.657 回答
0

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

self.Bind(wx.MY_EVENT, lambda evt: self.OnEventX(evt, handler=foo), id=12)
于 2012-05-12T22:21:30.767 回答