我有一个TextCtrl,它有一个EVT_KILL_FOCUS事件,我用它来验证字段的内容,在值错误时提醒用户。打开MessageBox后,我清除了该字段,并将焦点设置为我再次离开验证的字段。问题是应该出现在字段内的文本闪烁光标消失,我不知道为什么或如何修复它。此行为导致用户不知道焦点位于哪个字段中。
有没有人有任何想法?
...
self.txtCode = wx.TextCtrl(self, value='')
self.txtCode.Bind(wx.EVT_KILL_FOCUS, self.__onTxtCodeKillFocus)
self.txtCode.Bind(wx.EVT_CHAR_HOOK, self.__onTxtCodeTabKey)
def __validateTxtCodeContent(self):
if self.txtCode.GetValue() == "":
self.MessageBox(self, "Error Text", _("Warning"))
return False
return True
def __onTxtCodeKillFocus(self, event):
event.Skip()
if self.__validateTxtCodeContent() == False:
self.txtCode.SetValue("")
self.txtCode.SetFocus()
def __onTxtCodeTabKey(self, event):
key = event.GetKeyCode()
shift = event.ShiftDown()
# 9 = TAB, 13 = ENTER
if key != 9 and key != 13:
event.Skip()
return
elif key == 9:
if self.__validateTxtCodeContent():
if shift:
self.btnSave.SetFocus()
else:
self.txtDescription.SetFocus()
else:
self.txtCode.SetValue("")
self.txtCode.SetFocus()
else:
return False
我的验证不仅适用于空字段,而且例如只有空字段。
重要说明:在EVT_CHAR_HOOK事件中,也会发生此行为。
我也尝试过使用它:
self.txtCode.SetValue("")
self.txtCode.SetFocus()
self.txtCode.SetInsertionPointEnd()
self.txtCode.Refresh()
但它效果不佳。
答案 0 :(得分:1)
您无法从SetFocus()
处理程序中调用KILL_FOCUS
。最直接的解决方法是使用CallAfter()
稍稍调用它,但即使这会“起作用”,这也是一个非常糟糕的主意,因为你不应该阻止用户离开窗口 - 而且没有办法完全阻止它发生。
只需将代码标记为无效(例如更改其背景),但在丢失代码时不要尝试保留焦点。
P.S。在许多情况下,从焦点事件处理程序调用{{1}}也可能是一个坏主意,最好使用MessageBox()
或wxLogWarning()
来延迟显示消息框,直到下一个事件循环迭代。 / p>
答案 1 :(得分:0)
除了瓦迪姆已经说过的话:
你可以对击球进行验证" OK"按钮或对话框/面板即将关闭时
您可以使用wxValidator根据您手头的任务验证用户输入。