开发者

Inserting bold characters in pyGTK's TextView/TextBuffer

开发者 https://www.devze.com 2023-01-26 16:14 出处:网络
I have a TextView and a TextBuffer associated with it. When the user presses Ctrl+b, I would like the text to be start typing in bold until user presses Ctrl+b again.

I have a TextView and a TextBuffer associated with it.

When the user presses Ctrl+b, I would like the text to be start typing in bold until user presses Ctrl+b again.

I was trying my own methods, which weren't working, and then I found this post on the mailing list: http://www.daa.com.au/pipermail/pygtk/2009-April/016951.html

Same issue as me, and the solution someone gave is

Your application will have to handle the bookkeeping required to manage the tags in the TextBuffer. When text is inserted at the cursor your app has to catch a signal indicating the text is being inserted and then apply the required tags to the inserted text. I think this can be done by catching theTextBuffer "insert-text" signal (using connect_after() to make sure the text has already been inserted) and then applying the tags to the text in the callback.

So I attempted this. This is my 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()

the method make_bold() gets called from the main script whenever someone pressed Ctrl+b.

Theoretically, this is doing precisely what the mailing help said to do. But is not working. Text is not showing up bold as i type. If i press left arrow and move the cursor back, and then type a character, then the characters from the right of cursor tuns bold.

How can I accomplish this task?

Also, could someone add the tag 'textbuffer' to this? I cannot create new tags and I feel like that tag is more accurate than 'textview'


In the sample code you make the call to iter.backward_chars in TextBuffer.text_inserted but you never use that iter!, so I make a sample script to show you desired behavior and clarify:

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()
0

精彩评论

暂无评论...
验证码 换一张
取 消