首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在gtk.TextBuffer中等待用户输入的暂停?

如何在gtk.TextBuffer中等待用户输入的暂停?
EN

Stack Overflow用户
提问于 2010-01-31 14:58:38
回答 2查看 1.1K关注 0票数 1

我正在尝试用pygtk编写一个简单的基于gui的应用程序,它提供基于文本的标记的‘实时’预览。然而,标记处理在计算上可能非常昂贵,运行起来也很慢,因此在每次击键时更新预览并不是真正可行的。相反,我希望只在用户输入失效时运行更新。理想情况下,我应该让它在序列中的最后一次击键之后更新指定的时间间隔。

我研究过使用threading.Timer,方法是取消并重新启动计时器,以便在每次发出“已更改”信号时调用更新函数。我也尝试过使用gtk.idle_add(),但是我似乎不能让它工作。

下面是一个非常简单的例子--有没有人能建议最好的策略来实现我想要的东西,最好是举个例子?

代码语言:javascript
复制
import gtk

class example:
    def __init__(self):
        window = gtk.Window()
        window.set_title("example")
        window.resize(600,400)
        box = gtk.HBox(homogeneous = True, spacing = 2)
        buf = gtk.TextBuffer()
        buf.connect("changed", self.buf_on_change)
        textInput = gtk.TextView(buf)
        box.add(textInput)
        self.lbl = gtk.Label()
        box.add(self.lbl)
        window.add(box)
        window.connect("destroy", gtk.main_quit)
        window.show_all()

    def buf_on_change(self, buf):
        txt = buf.get_text(*buf.get_bounds())
        output = self.renderText(txt)
        self.lbl.set_text(output)

    def renderText(self, txt):
        # perform computation-intensive text-manipulation here
        output = txt
        return output

if __name__ == '__main__':
    example()
    gtk.main()
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-01-31 20:26:47

所以我想我找到了一个使用glib.timeout_add()而不是threading.Timer的解决方案

代码语言:javascript
复制
import gtk, glib

class example:
    def __init__(self):
        window = gtk.Window()
        window.set_title("example")
        window.resize(600,400)
        box = gtk.HBox(homogeneous = True, spacing = 2)
        self.buf = gtk.TextBuffer()
        self.buf.connect("changed", self.buf_on_change)
        textInput = gtk.TextView(self.buf)
        box.add(textInput)
        self.lbl = gtk.Label()
        box.add(self.lbl)
        window.add(box)
        window.connect("destroy", gtk.main_quit)
        window.show_all()

        self.timer = glib.timeout_add(1000, self.renderText)

    def buf_on_change(self, buf):
        glib.source_remove(self.timer)
        self.timer = glib.timeout_add(1000, self.renderText)


    def renderText(self):
        txt = self.buf.get_text(*self.buf.get_bounds())
        # perform computation-intensive text-manipulation here
        self.lbl.set_text(txt)
        return False

if __name__ == '__main__':
    example()
    gtk.main()

这似乎可以达到预期的效果,但由于我完全不熟悉gtk (以及桌面dui编程--以防您看不出来;),所以我想把这个问题留下来,希望有更多经验的人能对实现这种效果的最佳方法发表意见。我希望这没问题吧?

票数 1
EN

Stack Overflow用户

发布于 2010-01-31 17:03:25

所以我没有pygtk,所以我使用termios和一个自制的文本输入循环来模拟您的问题。但是关于计时器的部分也应该在gtk中起作用。请注意,如果您同时在多个线程中使用example类的对象,则对self.timer的访问不是线程安全的,此时您必须锁定self.txt和self.timer。

代码语言:javascript
复制
import termios, fcntl, sys, os, time, threading
fd = sys.stdin.fileno()

#just setting up the terminal input
oldterm = termios.tcgetattr(fd)
newattr = termios.tcgetattr(fd)
newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO
termios.tcsetattr(fd, termios.TCSANOW, newattr)
oldflags = fcntl.fcntl(fd, fcntl.F_GETFL)
fcntl.fcntl(fd, fcntl.F_SETFL, oldflags | os.O_NONBLOCK)


class example:
  def __init__(self, timeout):
    self.timeout = timeout
    self.timer = threading.Timer(timeout, self.render_text)
    self.txt = ''
    self.timer.start() #at the end of __init__ 

  def buf_on_change(self, buf):
    print "Got buffer:", buf, time.ctime()
    self.txt = self.txt + buf
    self.timer.cancel()   #won't do no harm if timer already elapsed
    self.timer = threading.Timer(self.timeout, self.render_text)
    self.timer.start()

  def render_text(self):
    print "starting intensive computation"
    print "rendering", self.txt
    time.sleep(3)
    print "stopping intensive computation"


# just my poor mans event loop for the text input
obj = example(3)
try:
    while 1:
        time.sleep(0.001) #just to keep processor cool
        try:
            buf = sys.stdin.read(5)
            obj.buf_on_change(buf)
        except IOError: pass
finally:
    termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm)
    fcntl.fcntl(fd, fcntl.F_SETFL, oldflags)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2170851

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档