繁体   English   中英

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

[英]Gtk 3 position attribute on insert-text signal from Gtk.Entry is always 0

我在管理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”的处理程序应该更新position参数(我们在不正确的情况下看到)中收到的值,以反映应该插入未来文本的位置并将其返回。 这很重要,因此在信号处理程序返回后光标会更改到正确的位置(这由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执行的任何操作, do_insert_text应用程序中的每个其他Gtk.Entry 如果您不继承,则覆盖Gtk.Editable提供的基本实现,该实现由应用程序中的所有其他Gtk.Entry小部件调用。 通过继承自Gtk.Editable,您只覆盖仅适用于您的自定义类的基本实现的“本地”副本。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM