在 Gtk::Entry 更改之前,我应该捕获啥信号来获取它的文本?
Posted
技术标签:
【中文标题】在 Gtk::Entry 更改之前,我应该捕获啥信号来获取它的文本?【英文标题】:What signal should I capture to grab the text of Gtk::Entry before it is changed?在 Gtk::Entry 更改之前,我应该捕获什么信号来获取它的文本? 【发布时间】:2013-08-28 02:27:28 【问题描述】:我正在使用 gtkmm 3(运行 Ubuntu 12.04 LTS)编写应用程序,现在正在使用 Gtk::Entry 控件。
我找不到要捕获的正确信号,因此我可以在更改之前获取 Gtk::Entry 缓冲区文本,并将其持久保存以维护更改记录。我知道在其他一些工具包中,提供了一个钩子来帮助实现这一点。 (我相信使用“阴影缓冲区”。)
我必须抓住什么信号才能做到这一点?该信号的插槽签名是什么?是否完全支持此功能?
【问题讨论】:
【参考方案1】:既然你要改变行为,最好从Gtk::Entry
继承:
class ValidatedEntry : public Gtk::Entry
Glib::ustring last_valid;
virtual void on_changed()
Glib::ustring text = get_text();
if (... validation here ...)
set_text(last_valid); // WARNING: will call this on_changed() again
else
last_valid = text;
Gtk::Entry::on_changed(); // propagate down
;
但是
这违背了可用性,这就是为什么它不是内置行为。用户不会因为他们输错了东西而喜欢文本恢复;他们可能会在意识到输入错误的字符之前按退格键。
您至少应该等到用户按下 Enter 键(即signal_activate
或覆盖on_activate()
),或者做一些不那么激烈的事情,例如显示警告图标。
【讨论】:
在文本发生变化之前没有信号可以捕捉到它。你能做的最好的就是拦截Gtk::Widget
的key_press_event
并在它到达Gtk::Entry
之前取消整个链(即从它返回true
);正确执行此操作的代码可能与我建议的一样大。
这不能回答问题,但似乎是解决问题的可行方法。然而,可用性方面与问题无关,并且做出了太多假设和概括 - 这完全取决于实现细节,这根本不是问题的一部分,属于 SE.UserExperience,而不是这里。
这似乎是 GTK Entry 控件的最佳解决方案。在输入新文本之前实现挂钩以获取旧文本的其他一些工具包使用临时“阴影缓冲区”保存并显示您的待处理编辑,直到您点击“输入”,然后提交到底层控制缓冲区等。
不知道您为什么添加“但是..” - 请参阅问题:我没有提及用户交互 - 您应该删除答案中不相关的部分。
这是 GTK+ 缺乏这种功能的理由。额外的空格是否会使输入无效?这会阻止我从倾向于在所选文本周围添加选项卡和换行符的网络浏览器复制/粘贴吗?如果我复制一个几乎正确的字符串,在粘贴后对其进行编辑怎么办? IME 呢?如果我是盲人,并且正在使用语音识别软件输入文本怎么办?在声称您的验证不会破坏可用性之前,您会费心测试所有这些情况吗?【参考方案2】:
你可以试试 GObject 的“通知”信号。它与 spy 属性结合使用。连接到“notify::text”将为“text”属性的每次修改调用你的回调,但第一个更改可能是设置初始值的设置器,然后你可以存储它。值得一试。
否则,您可以尝试将其存储在第一次触发“插入文本”或“删除文本”信号时。如果这似乎可行,请给使用一些反馈。
我也同意 DanielKO 的观点:从可用性的角度来看,修改用户输入只是令人讨厌和不好的做法。最好告诉她哪个字段有误,将焦点放在那里,和/或有一个按钮来重置为默认值,但不要对用户输入进行任何更改。
【讨论】:
实现与此无关,我已经看到这种方法存在足够多的问题来警告您。如果你不在乎,那是你的问题,但不要要求我们教你不好的做法。 不知道你在说什么,也不知道你为什么提到DanielKO的无关言论。 你有没有使用过这样的网站(我也在安装程序上看到过这个)假设当某些特定的文本条目(比如邮政编码或电话号码)已满时,你想使用 tab表格中的下一个条目?然后你意识到你犯了一个错误,现在每当你想用 shift-tab 键来纠正它时,脚本会再次将焦点发送到下一个空条目?这就是你正在陷入的可用性破坏。我的评论是相关的,因为 GTK+ 开发人员非常关心可用性,并且不会提供导致可用性问题的功能。以上是关于在 Gtk::Entry 更改之前,我应该捕获啥信号来获取它的文本?的主要内容,如果未能解决你的问题,请参考以下文章
TreeViewColumn标头中的PyGTK Entry小部件