在pyGTK的TextView/TextBuffer中插入粗体字符
我有一个文本视图(TextView)和一个与之关联的文本缓冲区(TextBuffer)。
当用户按下 Ctrl+b 时,我希望文本开始以粗体输入,直到用户再次按下 Ctrl+b。
我尝试了自己的方法,但都没有成功,然后我在邮件列表上找到了这个帖子:
http://www.daa.com.au/pipermail/pygtk/2009-April/016951.html这个问题和我遇到的一样,某人给出的解决方案是:
你的应用程序需要处理管理文本缓冲区中标签的相关工作。当文本在光标处插入时,你的应用需要捕捉到一个信号,表示文本正在被插入,然后将所需的标签应用到插入的文本上。我认为这可以通过捕捉 TextBuffer 的 "insert-text" 信号来实现(使用 connect_after() 确保文本已经被插入),然后在回调中将标签应用到文本上。
所以我尝试了这个。这是我的 textbuffer.py:
import gtk
import pango
class TextBuffer(gtk.TextBuffer):
def __init__(self):
gtk.TextBuffer.__init__(self)
self.connect_after('insert-text', self.text_inserted)
# A list to hold our active tags
self.tags_on = []
# Our Bold tag.
self.tag_bold = self.create_tag("bold", weight=pango.WEIGHT_BOLD)
def get_iter_position(self):
return self.get_iter_at_mark(self.get_insert())
def make_bold(self, text):
''' add "bold" to our active tags list '''
self.tags_on.append('bold')
def text_inserted(self, buffer, iter, text, length):
# A text was inserted in the buffer. If there are ny tags in self.tags_on, apply them
if self.tags_on:
print self.get_iter_position()
# This sets the iter back N characters
iter.backward_chars(length)
# And this applies tag from iter to end of buffer
self.apply_tag_by_name('bold', self.get_iter_position(), self.get_end_iter())
print self.get_iter_position()
每当有人按下 Ctrl+b 时,方法 make_bold() 就会从主脚本中被调用。
理论上,这正是邮件帮助中提到的做法。但实际上并没有成功。文本在我输入时并没有显示为粗体。如果我按左箭头把光标移动回去,然后再输入一个字符,光标右边的字符才会变成粗体。
我该如何完成这个任务呢?
另外,有人能把标签 'textbuffer' 加到这个帖子上吗?我不能创建新标签,我觉得这个标签比 'textview' 更准确。
1 个回答
5
在这个示例代码中,你在 TextBuffer.text_inserted
里调用了 iter.backward_chars
,但你并没有使用这个 iter!所以我写了一个示例脚本来展示你想要的效果,并做一些说明:
import gtk
import pango
class TextBuffer(gtk.TextBuffer):
def __init__(self):
gtk.TextBuffer.__init__(self)
self.connect_after('insert-text', self.text_inserted)
# A list to hold our active tags
self.tags_on = []
# Our Bold tag.
self.tag_bold = self.create_tag("bold", weight=pango.WEIGHT_BOLD)
def get_iter_position(self):
return self.get_iter_at_mark(self.get_insert())
def make_bold(self):
''' add "bold" to our active tags list '''
if 'bold' in self.tags_on:
del self.tags_on[self.tags_on.index('bold')]
else:
self.tags_on.append('bold')
def text_inserted(self, buffer, iter, text, length):
# A text was inserted in the buffer. If there are ny tags in self.tags_on, apply them
if self.tags_on:
# This sets the iter back N characters
iter.backward_chars(length)
# And this applies tag from iter to end of buffer
self.apply_tag_by_name('bold', self.get_iter_position(), iter)
def main():
window = gtk.Window()
window.connect('destroy', lambda _: gtk.main_quit())
window.resize(300, 300)
tb = TextBuffer()
tv = gtk.TextView(buffer=tb)
accel = gtk.AccelGroup()
accel.connect_group(gtk.keysyms.b,
gtk.gdk.CONTROL_MASK,gtk.ACCEL_LOCKED,
lambda a,b,c,d: tb.make_bold())
window.add_accel_group(accel)
window.add(tv)
window.show_all()
gtk.main()
if __name__ == '__main__':
main()