Domanda

I have successfully created a python GTK application using Gobject Introspection, and opened a source file in a GTKSourceView Widget.

I am attempting to scroll to place a specific line (line 150) into the center of the screen when the user clicks a button.

I have read how to (programmatically) scroll to a specific line in gtktextview/gtksourceview

and also the documentation surrounding GtkSourceViews, GTKTextView, and the buffer objects for both of these (it is my understanding that the sourceview inherits from the textview)

I have attempted to use the following methods:

-getting an iterator at line 150, and then using the scroll_to_iter() method - getting an iterator at line 150, making a mark at the iterator, and then using the scroll_to_mark() method

I know the iterators and marks are correct, because i can successfully use the place_cursor(iter) method and it successfully places the marker at the end of line 150, however either scrolling to the mark or the iterator using the given methods does nothing.

The scroll to mark method does not return a value, but the iterator method is returning false.

Can anyone please suggest a way to achieve this?

My testing code is as follows:

from gi.repository import Gtk
from gi.repository import GObject
from gi.repository import GtkSource

class MyApplication (Gtk.Window):

    def __init__(self, *args, **kwargs):
        Gtk.Window.__init__(self, *args, **kwargs)
        self.set_title("SourceView Test")
        self.set_size_request(400, 400)
        self.connect("destroy", Gtk.main_quit)
        self.create_widgets()
        self.show_all()

    def create_widgets(self):
        self.sourceview=GtkSource.View.new()        
        self.lm = GtkSource.LanguageManager.new()
        self.scrolledwindow = Gtk.ScrolledWindow()
        vbox = Gtk.VBox()
        self.add(vbox)
        vbox.pack_start(self.scrolledwindow,True,True,0)
        self.scrolledwindow.add_with_viewport(self.sourceview)      
        self.scrolledwindow.show_all()
        button = Gtk.Button("Jump To Line")
        button.connect("clicked", self.scroll_to_line_and_mark)
        self.open_file_in_srcview("/home/tel0s/source_android/system/core/adb/adb.c")
        vbox.pack_start(button, False, False, 5)

    def open_file_in_srcview(self,filename,*args,**kwargs):
        self.buffer = self.sourceview.get_buffer()
        self.filename = filename
        self.language = self.lm.guess_language(self.filename,None)
        self.sourceview.set_show_line_numbers(True)
        if self.language:
            self.buffer.set_highlight_syntax(True)
            self.buffer.set_language(self.language)
        else:
            print 'No language found for file "%s"' % self.filename
            self.buffer.set_highlight_syntax(False)
        txt = open(self.filename).read()
        self.buffer.set_text(txt)
        self.buffer.place_cursor(self.buffer.get_start_iter())


    def scroll_to_line_and_mark(self,*args,**kwargs):
        print "setting iterator"
        iterator = self.sourceview.get_buffer().get_iter_at_line(150)
        print iterator
        print "scrolling to iter"
        if self.sourceview.scroll_to_iter(iterator,0, False, 0.5, 0.5):
            print "done!"
        else:
            print "scrolling failed!!"

if __name__ == "__main__":
    MyApplication()
    Gtk.main()
È stato utile?

Soluzione

So the issue is the line:

self.scrolledwindow.add_with_viewport(self.sourceview)

According to the Gtk docs for scrolledwindow objects, you should only use add_with_viewport for objects that don't support scrolling. For those that do natively like GtkTextView (and so by inheritance GtkSourceView), you should use GtkContainer.add()...

Hope that helps

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top