Well, it's a bug in wxpython2.8.12.1, and has fixed in wxpython3.0.0.0, Thanks @GreenAsJade for reminding.
wx.Radiobox.SetBackgroundColour("pink") won't change the color of RadioButton until mouse pass by
Question
I've built a wx.Dialog
, with some wx.Radiobox
need to validate. If user doesn't make a choice, the validator wouldn't return True
and popup a wx.MessageBox
tells user that you should choose something. Meanwhile, the background color should have changed to pink.
The problem here is when using RadioBox.SetBackgroundColour("pink")
, the Background color of RadioBox's label text changed to pink, which is perfectly normal, but the background color for RadioButton's label text won't change until mouse pass by.
I'm wondering why this and how to fix it. I've looked up in official docs and googled, but find nothing. Anyone have idea?
The platform is win8.1x64 and python 2.7.3 and wxpython 2.8.12.1. For using Psychopy standalone package, the version of both python and wxpython are quite old.
The Dialog as follow, a quite simple one :
class Dlg(wx.Dialog):
"""A simple dialogue box."""
def __init__(self):
global app
app = wx.PySimpleApp()
wx.Dialog.__init__(self, None,-1)
self.sizer = wx.FlexGridSizer(cols=1)
def show(self, cancelBTN=False):
"""Show a dialog with 2 RadioBox"""
# add two RadioBox
RadioBox1 = wx.RadioBox(self, -1, label="Wierd color", choices=["", "choice A", "choice B"], validator=RadioObjectValidator())
RadioBox2 = wx.RadioBox(self, -1, label="Wierd color", choices=["", "choice A", "choice B"], validator=RadioObjectValidator())
RadioBox1.ShowItem(0, show=False) # Hide the first choice
RadioBox2.ShowItem(0, show=False) # Hide the first choice
RadioBox1.GetValue = RadioBox1.GetStringSelection
RadioBox2.GetValue = RadioBox2.GetStringSelection
self.sizer.Add(RadioBox1, 1, wx.ALIGN_LEFT)
self.sizer.Add(RadioBox2, 1, wx.ALIGN_LEFT)
# add buttons for OK
self.sizer.Add(wx.Button(self, wx.ID_OK), 1, flag=wx.ALIGN_RIGHT)
self.SetSizerAndFit(self.sizer)
if self.ShowModal() == wx.ID_OK:
pass
# do something
self.Destroy()
And Validator as this:
class RadioObjectValidator(wx.PyValidator):
""" This validator is used to ensure that the user has entered something
into the text object editor dialog's text field.
"""
def __init__(self):
""" Standard constructor.
"""
wx.PyValidator.__init__(self)
def Clone(self):
""" Standard cloner.
Note that every validator must implement the Clone() method.
"""
return RadioObjectValidator()
def Validate(self, win):
""" Validate the contents of the given RadioBox control.
"""
RadioBox = self.GetWindow()
choice = RadioBox.GetValue()
if not choice:
wx.MessageBox(u'Choose something please', u'info', wx.OK | wx.ICON_EXCLAMATION)
RadioBox.SetBackgroundColour("pink")
RadioBox.SetFocus()
RadioBox.Refresh()
return False
else:
RadioBox.SetBackgroundColour(
wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW))
RadioBox.Refresh()
return True
def TransferToWindow(self):
""" Transfer data from validator to window.
The default implementation returns False, indicating that an error
occurred. We simply return True, as we don't do any data transfer.
"""
return True # Prevent wxDialog from complaining.
def TransferFromWindow(self):
""" Transfer data from window to validator.
The default implementation returns False, indicating that an error
occurred. We simply return True, as we don't do any data transfer.
"""
return True # Prevent wxDialog from complaining.
And simply run like this:
if __name__ == "__main__":
test = Dlg()
test.show()
La solution