Fyne框架如何实现输入框失焦触发函数并保留原生聚焦样式
Fyne 输入框失焦校验问题解答
聚焦高亮线丢失修复
你自定义FocusLost()方法时覆盖了widget.Entry的原生实现,但没有调用父类方法。原生FocusLost()以及对应的焦点获取逻辑联动中包含焦点状态更新、样式重绘的核心逻辑,跳过调用就会导致聚焦时底部蓝色高亮线不显示。
修复只需要在重写的方法中优先调用原生实现即可:
func (e *dateEntry) FocusLost() { e.Entry.FocusLost() // 保留原生焦点逻辑与样式 e.Validate() }
添加这行代码后,输入框的所有焦点相关默认行为、样式表现都会和原生Entry完全一致。
简化失焦校验实现
Fyne 原生Entry默认在内容每次变更时触发校验,没有提供直接配置失焦校验的开关,所以重写FocusLost方法是官方推荐的标准实现方案,你原本的实现思路是正确的。如果觉得重复代码太多,可以做一次通用封装,后续所有需要失焦校验的输入框都可以直接复用:
// 全局定义一次通用失焦校验输入框 type blurValidateEntry struct { widget.Entry } func (e *blurValidateEntry) FocusLost() { e.Entry.FocusLost() e.Validate() } // NewBlurValidateEntry 直接传入校验函数即可创建失焦校验输入框 func NewBlurValidateEntry(validator func(string) error) *widget.Entry { entry := &blurValidateEntry{} entry.ExtendBaseWidget(entry) entry.Validator = validator return &entry.Entry }
后续业务代码里创建输入框不需要再重复写自定义类型逻辑,一行即可完成初始化:
// 提前把正则定义为全局变量,避免每次校验都重复编译影响性能 var datePattern = regexp.MustCompile(`(0?[1-9]|[12][0-9]|3[01])/(0?[1-9]|1[012])/((19|20)\d\d)`) func main() { // 其他窗口初始化逻辑省略 dateInput := NewBlurValidateEntry(func(s string) error { if s == "" { return fmt.Errorf("date required") } if !datePattern.MatchString(s) { return fmt.Errorf("date invalid") } return nil }) dateInput.SetPlaceHolder("DD/MM/YYYY") w.SetContent(dateInput) w.ShowAndRun() }
如果只是单个输入框临时需要失焦校验,不想做全局封装,也没有比你原本的写法更精简的实现——毕竟Fyne的控件扩展机制本身就要求按照ExtendBaseWidget+重写对应方法的模式来做,代码量已经是最小级别。
内容的提问来源于stack exchange,提问作者Alexis
相关产品推荐
相关产品推荐

