来自Gtk.Entry的插入文本信号的Gtk 3位置属性始终为0 [英] Gtk 3 position attribute on insert-text signal from Gtk.Entry is always 0

查看:149
本文介绍了来自Gtk.Entry的插入文本信号的Gtk 3位置属性始终为0的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法管理由Gtk.Entry小部件发出的插入文本信号。考虑下面的例子:

  from gi.repository import Gtk 

def on_insert_text(entry,new_text, new_text_length,position):
print(position)
$ b $ 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()

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



最后我想要做的是验证文本的输入在小部件中限制将被接受的字符。我打算这样做的方式与文档中提供的示例中的所有字符都转换为大写字母相似。

'insert-text'的处理程序预计会更新位置参数(我们在其中看到的不正确)中收到的值,以反映未来文本应插入的位置并将其返回。这很重要,所以在信号处理程序返回后(这是通过 gtk 完成的)将光标更改为正确的位置。如果你没有更新并返回,那么游标保持在0位置。



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



经过一些进一步的调查后,我发现问题在于处理 pygobject 中的输入/输出参数,这在大多数情况下运行良好,但不适用于信号(参见错误644927



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



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



您可以在 Gtk.Entry 上使用此方法进行输入验证/ code>。处理我的用例的例子是:

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

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

def __init __(self):
super(MyEntry,self).__ init __()
$ b $ def do_insert_text(self,new_text,length,position):
regexp = re.compile ^(\ d * \。?\d *)$')

如果new_text =='。'和'。'在self.get_text()中:
返回位置
elif regexp.match(new_text)不是:
self.get_buffer()。insert_text(position,new_text,length)
返回位置+长度

返回位置

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

Gtk.main()

在这种情况下, tion参数被正确接收并且返回值被pygobject看到并使用,所以光标被正确定位。

重要注意事项
除了Gtk.Entry外,您还必须继承Gtk.Editable。如果你不这样做,你将开始在 do_insert_text 中执行验证或其他操作,并将其应用于所有其他 Gtk.Entry 在你的应用程序中。如果您没有继承,那么您将覆盖由应用程序中所有其他 Gtk.Entry 窗口小部件调用的Gtk.Editable提供的基本实现。通过从Gtk.Editable继承,您只覆盖仅适用于您的自定义类的基本实现的'local'副本。


I am having trouble in managing the insert-text signal emitted by the Gtk.Entry widget. Consider the following example:

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()

The position attribute I am receiving on the signal handler is always 0. Unless I am misunderstanding this should it not be the position where the next text should be inserted?

In the end what I want to do is to validate the entry of text in the widget to restrict the characters that will be accepted. The way I plan to do this is similar to the example provided in the documentation in which all characters are transformed to uppercase.

解决方案

The handler of 'insert-text' is expected to update the value received in the position parameter (which we have seen in incorrect) to reflect the position from which future text should be inserted and return it. This is important so the cursor is changed to the right place after the signal handler returns (this is done by gtk). If you don't update and return then the cursor remains at position 0.

After following the suggestion of using entry.get_position() to obtain the right position value I found out that the update and return of position in my handler was being ignored by pygobject. It behaved as if I was not returning anything (the cursor remained at position 0). Setting the position inside the handler did not help, because gtk would change it back again to 0 after the handler returned.

After some further investigation I learned that the issue lies with the handling of in/out parameters in pygobject which works well in most cases but not with signals (see bug 644927)

If you use connect to attach a handler to the signal and the signal has an in/out parameter you may not receive what you expect in the handler and even if you return a value this value will probably not be handled correctly by pygobject either. Anything that depends on that value will probably not work as expected (e.g. advance the cursor to the new position)

There is a solution though which is to override the associated vfunc (the default handler) instead of connecting with connect(). This solution implies deriving from the base class but it does work.

You can use this method for input validation/transformation on Gtk.Entry. An example handling my use case would be:

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()

In this case the position parameter is received correctly and the return value is seen and used by pygobject so the cursor is correctly positioned.

Important Note You have to inherit from Gtk.Editable in addition to Gtk.Entry. If you do not do so you will start seeing the validation or whatever you do inside do_insert_text applying to every other Gtk.Entry in your application. If you do not inherit you are overriding the base implementation provided by Gtk.Editable which is called by all other Gtk.Entry widgets in your application. By inheriting from Gtk.Editable you override only the 'local' copy of the base implementation which only applies to your custom class.

这篇关于来自Gtk.Entry的插入文本信号的Gtk 3位置属性始终为0的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆