持续检查单选按钮状态 [WxPython]

0 投票
2 回答
648 浏览
提问于 2025-04-18 10:24

我有一个列表框,里面有一组字符串。想要显示的字符串取决于用户选择了哪个单选按钮。我希望用户在使用这个表单时,如果他们改变了单选按钮,列表框能够自动更新。

这是我的代码(我省略了t87和t89的数组,因为它们很长,假设它们是存在的):

 def OnBtnSuperTesting(self, event):
    class MainWindow(wx.Frame):

        def __init__(self, parent, title):

            self.dirname=''

            wx.Frame.__init__(self, parent, title=title, size=(320,440))
            self.SetBackgroundColour(wx.WHITE)
            self.CenterOnScreen()
            self.CreateStatusBar()
            self.radioT89 = wx.RadioButton(self, -1, 'T89 only', pos = (2,0), style = wx.RB_GROUP)
            self.radioT87 = wx.RadioButton(self, -1, 'T87 only', pos = (154, 0))
            self.radioKeySort = wx.RadioButton(self, -1, 'Sort by Key', pos = (2,40), style = wx.RB_GROUP)
            self.radioAtoZ = wx.RadioButton(self, -1, 'Sort Name A-Z', pos = (2,60))
            self.radioZtoA = wx.RadioButton(self, -1, 'Sort Name Z-A', pos = (2,80))
            self.checkCode = wx.CheckBox(self, -1, 'Generate Code', pos = (154,40))
            self.checkBuild = wx.CheckBox(self, -1, 'Generate Build Report', pos = (154, 60))
            self.ln = wx.StaticLine(self, -1, pos = (0,15), size = (300,3), style = wx.LI_HORIZONTAL)
            self.ln2 = wx.StaticLine(self, -1, pos = (150,15), size = (3,100), style = wx.LI_VERTICAL)

            self.radioT87.Bind(wx.EVT_RADIOBUTTON, self.updateList)
            #self.Bind(wx.EVT_RADIOBUTTON, self.radioT89, self.updateList())




            self.listbox = wx.ListBox(self, -1, pos = (0,120), size = (300,200), choices = T89, style = (wx.LB_SINGLE|wx.LB_HSCROLL))
            self.go = wx.Button(self,-1, label = 'Go!', pos = (110, 325))



            # Setting up the menu.
            filemenu= wx.Menu()
            menuAbout= filemenu.Append(wx.ID_ABOUT, "&About"," Information about this program")
            menuExit = filemenu.Append(wx.ID_EXIT,"E&xit"," Terminate the program")

            # Creating the menubar.
            menuBar = wx.MenuBar()
            menuBar.Append(filemenu,"&File") 
            self.SetMenuBar(menuBar) 

            # Events.
            self.Bind(wx.EVT_MENU, self.OnExit, menuExit)
            self.Bind(wx.EVT_MENU, self.OnAbout, menuAbout)

            self.SetAutoLayout(1)

            self.Show()



        def OnExit(self,e):
            self.Close(True)  # Close the frame.

        def updateList(self):
            if  self.radioT87.GetValue() == True:
                choices = T87
                self.listbox.Set(choices)
            else:
                choices = T89
                self.listbox.Set(choices)
    app = wx.App(False)
    frame = MainWindow(None, "Supervisory Testing")
    app.MainLoop()

2 个回答

0

我决定重写原作者的代码,来展示如何将两个单选按钮(RadioButton)绑定到两个不同的事件处理器,并更新列表框(ListBox):

import wx

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

    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        wx.Frame.__init__(self, None, title="Radios!")
        panel = wx.Panel(self)

        sizer = wx.BoxSizer(wx.VERTICAL)

        self.radioAtoZ = wx.RadioButton(panel, label='Sort Name A-Z',
                                        style = wx.RB_GROUP)
        self.radioAtoZ.Bind(wx.EVT_RADIOBUTTON, self.sortAZ)
        sizer.Add(self.radioAtoZ, 0, wx.ALL|wx.EXPAND, 5)

        self.radioZtoA = wx.RadioButton(panel, label='Sort Name Z-A')
        self.radioZtoA.Bind(wx.EVT_RADIOBUTTON, self.sortZA)
        sizer.Add(self.radioZtoA, 0, wx.ALL|wx.EXPAND, 5)

        choices = ["aardvark", "zebra", "bat", "giraffe"]
        self.listbox = wx.ListBox(panel, choices=choices)
        sizer.Add(self.listbox, 0, wx.ALL, 5)

        panel.SetSizer(sizer)

        self.Show()

    #----------------------------------------------------------------------
    def sortAZ(self, event):
        """"""
        choices = self.listbox.GetStrings()
        choices.sort()
        self.listbox.SetItems(choices)

    #----------------------------------------------------------------------
    def sortZA(self, event):
        """"""
        choices = self.listbox.GetStrings()
        choices.sort()
        choices.reverse()
        self.listbox.SetItems(choices)

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

你可以看看下面这篇维基文章,了解这种绑定方式和其他方式的区别:

通常,当你创建一组执行不同操作的控件时,你会将它们绑定到不同的事件处理器。如果你想把所有的单选按钮绑定到同一个处理器,那么你可能需要给每个控件起一个独特的名字,这样在处理器中就能知道是哪个按钮被按下了。然后你可以用一系列的if语句来决定对列表框做什么。这里有个教程讲的就是这方面的内容:

0

当你创建每个单选按钮时,可以设置一个绑定事件。这个事件的作用是,当绑定的事件发生时,执行一个命令函数。在你的例子中,它看起来像这样:

self.Bind(wx.EVT_RADIOBUTTON,self.RadioButton,self.DoSomething)

解释:

wx.EVT_RADIOBUTTON

这是当用户改变单选按钮状态时触发的事件。这个事件可能会有一些属性,也可能没有。

self.RadioButton

这是你想要绑定的单选按钮。在你的例子中是“self.radioAtoZ”或者类似的东西。

self.DoSomething

这是回调函数。你可以把它定义成你想要的样子,比如:

def DoSomething(self):
    if self.radioAtoZ.getStatus():
        rearrangeNumbersFromAtoZ
        print 'Re-arranged numbers from A to Z'
    else:
        etc.

编辑:

self.RadioButton.Bind(EVT_RADIOBUTTON, self.DoSomething)

你的self.DoSomething的结构应该是这样的:

Class MainWindow:
     def __init_(self, parent):


     def DoSomething(self):
         #dostuff

另外,针对你提到的其他评论:当一个函数在绑定事件中被调用时,默认会把事件传递给这个函数。此外,所有函数都有一个“self”参数,所以总共有两个参数。你需要修改以下内容:

def DoSomething(self, event):
      #dostuff

撰写回答