如何在 gtk.TextBuffer 中等待用户输入暂停?
我正在尝试在 pygtk 中编写一个简单的基于 gui 的应用程序,它提供基于文本的标记的“实时”预览。然而,标记处理的计算成本可能相当高,而且运行速度很慢,因此在每次击键时更新预览实际上并不可行。相反,我希望仅在用户输入失败时才运行更新。理想情况下,我希望它在序列中最后一次击键后更新指定的间隔。
我研究过使用 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()
I'm trying to write a simple gui-based application in pygtk which provides 'live' previewing of text-based markup. The markup processing, however, can be quite computationally expensive and slow to run, so updating the preview on every keystroke is not really viable. Instead I'd like to have the update run only when user input lapses. Ideally, I'd have it update a specified interval after the last keystroke in a sequence.
I've looked into using threading.Timer
, by cancelling and re-starting a timer to invoke the update function each time the "changed" signal is emitted. I've also tried to use gtk.idle_add()
, but I can't seem to get it working.
Below is a very simple example - could someone suggest the best strategy to achieve what I'm after, preferably with an example?
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()
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
所以我想我找到了一个使用
glib.timeout_add()
而不是threading.Timer
的解决方案:这似乎按预期工作,但因为我对 gtk 完全陌生(以及一般的桌面 dui 编程 - 以防万一您无法分辨;) ) 我想将这个问题保留下来,希望有更多经验的人可以对实现这种效果的最佳方法发表评论。我希望这样可以吗?
so I think I found a solution using
glib.timeout_add()
instead ofthreading.Timer
:this seems to work as desired, but since I'm completely new to gtk (and desktop dui programming in general - in case you couldn't tell ;) ) I'd like to leave this question open in the hope that someone more experience might comment on the best way to achieve this kind of effect. I hope that's okay?
所以我没有 pygtk,所以我使用 termios 和一个自制的文本输入循环来模仿你的问题。但是关于计时器的部分也应该在 gtk 中工作。请注意,如果您在多个线程中使用类示例的对象,同时必须锁定 self.txt 和 self.timer,则对 self.timer 的访问不是线程安全的。
So i did not have pygtk, so i mimiced your problem using termios and a home made loop for the text input. But the part about the timer should work in gtk too. Please note that the access to the self.timer is not thread safe if you use an object of class example within more than one thread at the time you must lock self.txt and self.timer.