wxPython和(分组)单选按钮问题:
我有三个单独绑定的单选按钮,我看到这给了我一个单选按钮A,B或C的选择,其中一个总是被选中 - 我很欣赏这是wx.RB_GROUP的本质样式;
是否可以通过单击单选按钮取消选择所有按钮,如A = B = C = False?我已经简化了代码(下面),其中重置按钮执行此功能,但理想情况下我只想在GUI中取消选择。
import wx
class MyForm(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1, "Tutorial", size=(300,250))
panel = wx.Panel(self, wx.ID_ANY)
self.radio1 = wx.RadioButton(panel, label="A", pos=(20,40), style=wx.RB_GROUP)
self.radio2 = wx.RadioButton(panel, label="B", pos=(20,70))
self.radio3 = wx.RadioButton(panel, label="C", pos=(20,100))
btn = wx.Button(panel, label="Check", pos=(20,140))
rst = wx.Button(panel, label="Reset", pos=(20,170))
btn.Bind(wx.EVT_BUTTON, self.onBtn)
rst.Bind(wx.EVT_BUTTON, self.onRst)
def onBtn(self, event):
print "A = ", self.radio1.GetValue()
print "B = ", self.radio2.GetValue()
print "C = ", self.radio3.GetValue()
print "\n\n"
def onRst(self, event):
self.radio1.SetValue( 0 )
self.radio2.SetValue( 0 )
self.radio3.SetValue( 0 )
if __name__ == "__main__":
app = wx.PySimpleApp()
frame = MyForm().Show()
app.MainLoop()
答案 0 :(得分:4)
据我所知,wxPython本身不支持。此外,这不是任何UI中单选按钮的预期行为,因此我首先想到的是您的界面设计不正确。您是否考虑过添加另一个“无”单选按钮,这在逻辑上等同于您的所有单选按钮都没有被选中?为什么不呢?
然而,我确实试图破解你的解决方案,但没有成功。事实上,考虑到我遇到的困难,我非常怀疑即使 可以编程这种行为,你仍然可以更好地寻找替代方案。
我的第一个想法是通过创建自定义wx.RadioButton
来覆盖wx.RadioButton
处理选择的方式。以下是我发现的一些问题:
wx.EVT_RADIOBUTTON
仅在系统已更改单选按钮的值后才被捕获,因此我实际上无法覆盖行为wx.EVT_RADIOBUTTON
(当没有指定id
时),因此无法预测系统是否有进一步排队的更改,这可能会覆盖您对按钮值所做的任何更改。wx.EVT_RADIOBUTTON
wx.EVT_LEFT_DOWN
和wx.EVT_LEFT_UP
个事件,这两个事件都没有完全描述单选按钮如何知道它被点击了然后我转向自定义wx.RadioBox
,但我很快意识到没有方法可以完全取消选择收音机盒内的按钮,这意味着它也不是一个可接受的选择。
我想您可以编写某种包含多个wx.Panel
对象的自定义wx.CheckBox
,并尝试强制一次只选择最多一个框,但是您再次遇到此问题不是用户希望复选框工作的方式。我以前见过这种行为,但每次它都让我觉得奇怪,我不能推荐它。此外,还需要付出相当大的努力才能发展。
我能找到的最接近的解决方案是双击时取消选择的自定义wx.RadioButton
。这里的问题是用户不希望双击取消选择单选按钮,所以你现在需要考虑如何教他们这个。
class DeselectableRB(wx.RadioButton):
def __init__(self, parent, label, pos=None, style=0):
#do the default init
wx.RadioButton.__init__(self, parent, label=label, pos=pos, style=style)
#catch double clicks
self.Bind(wx.EVT_LEFT_DCLICK, self.onDClick)
def onDClick(self, event):
self.SetValue(0)
但是,我仍然强烈认为标题为“无”的额外wx.RadioButton
是您的最佳解决方案,因为它只需要很少的工作量,并且符合用户对单选按钮应如何工作的期望(使其更直观)
答案 1 :(得分:1)
这可以取消选择单选按钮,就像它是一个复选框:
import wx
class MyForm(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1, "Tutorial", size=(300,250))
panel = wx.Panel(self, wx.ID_ANY)
self.radio1 = wx.RadioButton(panel, label="A", name='radio1', pos=(20,40), style=wx.RB_GROUP)
self.radio2 = wx.RadioButton(panel, label="B", name='radio2', pos=(20,70))
self.radio3 = wx.RadioButton(panel, label="C", name='radio3', pos=(20,100))
self.radio1.Bind(wx.EVT_LEFT_DOWN, self.OnRB)
self.radio2.Bind(wx.EVT_LEFT_DOWN, self.OnRB)
self.radio3.Bind(wx.EVT_LEFT_DOWN, self.OnRB)
btn = wx.Button(panel, label="Check", pos=(20,140))
rst = wx.Button(panel, label="Reset", pos=(20,170))
btn.Bind(wx.EVT_BUTTON, self.onBtn)
rst.Bind(wx.EVT_BUTTON, self.onRst)
def OnRB(self, event):
event.GetEventObject().SetValue(not event.GetEventObject().GetValue())
def onBtn(self, event):
print "A = ", self.radio1.GetValue()
print "B = ", self.radio2.GetValue()
print "C = ", self.radio3.GetValue()
print "\n\n"
def onRst(self, event):
self.radio1.SetValue( 0 )
self.radio2.SetValue( 0 )
self.radio3.SetValue( 0 )
if __name__ == "__main__":
app = wx.PySimpleApp()
frame = MyForm().Show()
app.MainLoop()
请注意,我添加到您的代码中的所有内容都是:
self.radio1.Bind(wx.EVT_LEFT_DOWN, self.OnRB)
self.radio2.Bind(wx.EVT_LEFT_DOWN, self.OnRB)
self.radio3.Bind(wx.EVT_LEFT_DOWN, self.OnRB)
def OnRB(self, event):
event.GetEventObject().SetValue(not event.GetEventObject().GetValue())