0

我有一个 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()

但效果并不好。

4

2 回答 2

1

您不能SetFocus()KILL_FOCUS处理程序调用。最直接的解决方法是CallAfter()稍微稍后调用它,但即使这会“工作”,这是一个非常糟糕的主意,因为您不应该阻止用户离开窗口——而且没有办法完全阻止它无论如何都会发生。

只需将代码标记为无效(例如更改其背景),但不要在失去焦点时尝试保持焦点。

PSMessageBox()在许多情况下,从焦点事件处理程序调用可能也是一个坏主意,最好使用wxLogWarning()CallAfter()延迟显示消息框,直到下一次事件循环迭代。

于 2018-01-24T15:09:25.043 回答
0

除了瓦迪姆已经说过的话:

  • 您可以在点击“确定”按钮或对话框/面板即将关闭时进行验证

  • 您可以根据手头的任务使用 wxValidator 来验证用户输入。

于 2018-01-24T15:19:46.497 回答