我想从其"更改"信号处理程序中更改urwid.Edit的文本.但是,它没有做任何事情.最小的工作示例:
import urwid
input_line = urwid.Edit(multiline=True)
def input_change(widget, text):
if text.endswith("\n"):
input_line.set_edit_text('')
urwid.connect_signal(input_line, 'change', input_change)
urwid.MainLoop(urwid.Filler(input_line)).run()
Run Code Online (Sandbox Code Playgroud)
如果按Enter键,它实际上会调用.set_edit_text(),但文本保持不变.我如何实现我想要的目标?
正如您在源代码中看到的那样,该set_edit_text方法会发出您的"change"事件,然后立即将其设置_edit_text为实际值.*
您也可以通过例如input_line.edit_text在您之后立即记录set_edit_text以确定您已成功更改它来验证这一点.
你需要做的是子Edit窗口小部件,并覆盖set_edit_text,**不处理"change"信号.那很容易.
例如:
def set_edit_text(self, text):
if text.endswith('\n'):
super().set_edit_text('')
else:
super().set_edit_text(text)
Run Code Online (Sandbox Code Playgroud)
如上所述,GUI框架有一个很好的理由让事件在应用更改之前触发:这为事件处理程序提供了查看当前值和新值的方法.
当然,GUI框架也有很好的理由让事件在应用更改后触发.
一些框架提供了两者.例如,在Cocoa中,您通常会fooWillChange:在更改之前收到一条消息,之后会收到一条消息fooDidChange:.此外,在某些框架中,"before"事件为您提供了一种影响事件处理方式的方法(替换其中一个值,吞下事件以使其不会被链接传递等).然后是Tkinter,它提供了一些方法来完成所有这些不同的事情,但它们彼此完全不同,并且从小部件到小部件......
对于没有所有可能选项的框架来说,这是一个错误吗?嗯,框架太大而且太笼统有一个缺点.开发和维护更难,而且更难学习.我认为urwid在这里做出了合理的选择.特别是因为它是用相对简单的纯Python编写的,具有类类层次结构,可以轻松覆盖您不喜欢的任何行为.
但是,您可以将其称为文档错误,Urwid不会告诉您使用哪种信号逻辑(在事件之前是不可变的),并且提供很少的指导来覆盖什么来自定义行为.
*值得注意的是,你的change处理程序正在调用中set_edit_text.在urwid中,set_edit_text从这个处理程序调用不是问题,但在许多其他UI库中,它可能导致无限递归或奇怪的行为.
**你当然可以monkeypatch Edit而不是子类,除非你有特别的理由这样做,我不会.
| 归档时间: |
|
| 查看次数: |
1727 次 |
| 最近记录: |