代码之家  ›  专栏  ›  技术社区  ›  simon ArrowInTree

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

  •  1
  • simon ArrowInTree  · 技术社区  · 16 年前

    我已经考虑过使用 threading.Timer ,每次发出“已更改”信号时,取消并重新启动计时器以调用更新功能。我也尝试过使用 gtk.idle_add() ,但我似乎无法让它工作。

    下面是一个非常简单的例子——有人能提出实现我追求的目标的最佳策略吗,最好举个例子?

    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()
    
    2 回复  |  直到 16 年前
        1
  •  1
  •   simon ArrowInTree    16 年前

    glib.timeout_add() 而不是 threading.Timer :

    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编程——以防您不知道;)是完全陌生的)我想留下这个问题,希望有更多经验的人能够对实现这种效果的最佳方式发表意见。我希望没问题吧?

        2
  •  0
  •   snies    16 年前

    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)