简体   繁体   English

PyGTK:筛选键盘输入到Entry小部件时,在打开大缓冲区时无法正确设置光标位置

[英]PyGTK: When filtering keyboard input to an Entry widget, can't correctly set the cursor position while opening a large buffer

I am writing a program with PyGTK for navigating large (>20 MB) text files. 我正在用PyGTK编写一个程序来导航大(> 20 MB)文本文件。 I am using a TextViewer widget for this, which handles them quite well except it takes several seconds to finish filling the corresponding TextBuffer. 我为此使用了TextViewer小部件,该控件处理得很好,只不过需要花费几秒钟才能完成填充相应的TextBuffer。 Meanwhile, I also have several dialogs that require filtering on their input (only hexadecimal digits or something). 同时,我还有几个对话框需要过滤其输入(仅十六进制数字或其他内容)。 I pass the characters I want to allow and the name of a signal to this function: 我将要允许的字符和信号名称传递给此函数:

def FilterText(self, chars, signal):

    def Filt(entry, text, length, position):
        position = entry.get_position()
        chrs = set(chars)
        realtext = ''.join([c for c in text if c in chrs])
        if len(realtext) > 0:
            entry.handler_block_by_func(Filt)
            entry.insert_text(realtext, position)
            entry.handler_unblock_by_func(Filt)
            newPos = position + len(realtext)
            gobject.idle_add(entry.set_position, newPos)
        entry.stop_emission(signal)
    return Filt

And then connect the result to the Entry widget's handler for that signal. 然后将结果连接到该信号的Entry小部件的处理程序。 This works, except that while the TextBuffer is being filled, none of the entry.set_position calls that were queued up get run until it finished. 这是可行的,除了在填充TextBuffer时,直到排队的所有entry.set_position调用都不会运行。 The result is that the cursor is stuck at the beginning of the Entry and everything typed is backwards which is, needless to say, quite annoying. 结果是光标停留在Entry的开头,并且键入的所有内容都是向后的,这无疑很烦人。 This is presumably because there is no idle time until the TextBuffer is filled. 大概是因为在TextBuffer填满之前没有空闲时间。 Is there any way to work around this and allow the correct behavior when typing into a filtered Entry widget? 有什么办法可以解决此问题,并在输入经过过滤的Entry小部件时允许正确的行为? (It should be possible, as no such problem is encountered with an unfiltered one) Calling entry.set_position directly doesn't work for some reason. (这应该是可能的,因为未经过滤的问题不会遇到此类问题。)由于某些原因,直接调用entry.set_position无效。

Finally figured it out--change the call 终于找到答案-更改通话

gobject.idle_add(entry.set_position, newPos)

To

gobject.timeout_add(0, entry.set_position, newPos)

Since entry.set_position returns None, it will call it once immediately, then never again, doing exactly what I wanted. 由于entry.set_position返回None,它将立即执行一次,然后再执行一次即可,完全按照我的要求进行。

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

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