python - 来自 Gtk.Entry 的插入文本信号上的 Gtk 3 位置属性始终为 0

标签 python python-3.x gtk gtk3 pygobject

我在管理 Gtk.Entry 小部件发出的插入文本信号时遇到了问题。考虑以下示例:

from gi.repository import Gtk

def on_insert_text(entry, new_text, new_text_length, position):
    print(position)

entry = Gtk.Entry()
entry.connect('insert-text', on_insert_text)

window = Gtk.Window()
window.connect("destroy", lambda q: Gtk.main_quit())
window.add(entry)
window.show_all()
Gtk.main()

我在信号处理程序上收到的位置属性始终为 0。除非我误解了这不应该是应该插入下一个文本的位置吗?

最后我想做的是验证小部件中的文本输入以限制将被接受的字符。我计划这样做的方式类似于文档中提供的示例,其中所有字符都转换为大写。

最佳答案

'insert-text' 的处理程序应该更新位置参数中收到的值(我们已经看到不正确)以反射(reflect) future 文本应该插入的位置并返回它。这很重要,因此在信号处理程序返回后光标会更改到正确的位置(这由 gtk 完成)。如果您不更新并返回,那么光标将保留在位置 0。

遵循使用 entry.get_position() 的建议后为了获得正确的位置值,我发现我的处理程序中位置的更新和返回被 pygobject 忽略了.它表现得好像我没有返回任何东西(光标保持在位置 0)。在处理程序中设置位置没有帮助,因为 gtk将在处理程序返回后再次将其更改回 0。

经过进一步调查,我了解到问题出在 pygobject 中输入/输出参数的处理上。在大多数情况下效果很好,但不适用于信号(参见 bug 644927 )

如果您使用 connect 将处理程序附加到信号并且该信号具有输入/输出参数,您可能无法在处理程序中收到您期望的内容,即使您返回一个值,该值也可能不会被处理通过 pygobject 正确任何一个。任何依赖于该值的东西都可能无法按预期工作(例如,将光标前进到新位置)

虽然有一个解决方案是覆盖关联的 vfunc(默认处理程序)而不是连接 connect() .此解决方案意味着从基类派生,但它确实有效。

您可以使用此方法在 Gtk.Entry 上进行输入验证/转换.处理我的用例的示例是:

import re
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk


class MyEntry(Gtk.Entry, Gtk.Editable):

    def __init__(self):
        super(MyEntry, self).__init__()

    def do_insert_text(self, new_text, length, position):
        regexp = re.compile('^(\d*\.?\d*)$')

        if new_text == '.' and '.' in self.get_text():
            return position
        elif regexp.match(new_text) is not None:
            self.get_buffer().insert_text(position, new_text, length)
            return position + length

        return position

entry = MyEntry()
window = Gtk.Window()
window.connect("destroy", lambda q: Gtk.main_quit())
window.add(entry)
window.show_all()

Gtk.main()

在这种情况下,位置参数被正确接收,返回值被 pygobject 看到和使用,因此光标被正确定位。

重要提示 除了 Gtk.Entry 之外,您还必须继承 Gtk.Editable。如果你不这样做,你将开始看到验证或你在 do_insert_text 中所做的任何事情。适用于所有其他 Gtk.Entry在你的应用程序中。如果你不继承,你将覆盖 Gtk.Editable 提供的基础实现,它被所有其他调用 Gtk.Entry您的应用程序中的小部件。通过从 Gtk.Editable 继承,您仅覆盖基实现的“本地”副本,该副本仅适用于您的自定义类。

关于python - 来自 Gtk.Entry 的插入文本信号上的 Gtk 3 位置属性始终为 0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38815694/

相关文章:

python - 我可以从 South 生成适用于不同数据库 [sqlite 和 postgresql] 的模式迁移吗?

python - 如何确保绘图的 x 轴和 y 轴大小相等?

python - 如何使用 beautifulsoup 解析来自特定站点的任何文章以及如何预览该链接的图像?

python - 将菜单添加到 GtkMenuToolButton (Python)

python - pytz:获取所有时区,现在是特定时间

python - crontab 自动 python 脚本不会上传到 dropbox

python - 给定两个可能的字典键,如何获取实际设置的一个

python - 遍历 *args 重置计数器

ubuntu - "Gtk WARNING: gtk_disable_setlocale() must be called before gtk_init()"在 gdl(gnu 数据语言)中调用绘图

c - 如何从另一个线程调用 Gtk API?