Skip to content

Instantly share code, notes, and snippets.

@otsaloma
Created February 26, 2012 01:43
Show Gist options
  • Save otsaloma/1912166 to your computer and use it in GitHub Desktop.
Save otsaloma/1912166 to your computer and use it in GitHub Desktop.
Line numbers in Gtk3 text view margin
#!/usr/bin/env python3
from gi.repository import Gtk
from gi.repository import Pango
def on_text_view_draw(text_view, cairoc):
print("Drawing...")
# XXX: Rest of function not yet ported.
text_buffer = text_view.get_buffer()
bounds = text_buffer.get_bounds()
text = text_buffer.get_text(*bounds)
nlines = text.count("\n") + 1
layout = pango.Layout(text_view.get_pango_context())
layout.set_markup("\n".join([str(x + 1) for x in range(nlines)]))
layout.set_alignment(Pango.Alignment.RIGHT)
width = layout.get_pixel_size()[0]
text_view.set_border_window_size(Gtk.TextWindowType.RIGHT, width + 4)
y = -text_view.window_to_buffer_coords(Gtk.TextWindowType.RIGHT, 2, 0)[1]
window = text_view.get_window(Gtk.TextWindowType.RIGHT)
window.clear()
text_view.style.paint_layout(window=window,
state_type=Gtk.STATE_NORMAL,
use_text=True,
area=None,
widget=text_view,
detail=None,
x=2,
y=y,
layout=layout)
text_view = Gtk.TextView()
text_buffer = text_view.get_buffer()
text_buffer.insert_at_cursor("ABC\nabc")
text_view.set_border_window_size(Gtk.TextWindowType.RIGHT, 24)
text_view.connect("draw", on_text_view_draw)
scroller = Gtk.ScrolledWindow()
scroller.set_shadow_type(Gtk.ShadowType.IN)
scroller.add(text_view)
window = Gtk.Window()
window.connect("delete-event", Gtk.main_quit)
window.set_position(Gtk.WindowPosition.CENTER)
window.set_default_size(300, 100)
window.set_border_width(12)
window.add(scroller)
window.show_all()
Gtk.main()
@turboiii
Copy link

I found a solution to display lines number in gtk3

#!/usr/bin/env python
# coding: utf-8 
from gi.repository import Gtk,Gdk
from gi.repository import Pango


def recup_lignes(textbuffer,premier_y, dernier_y, coords_buffer, numeros):
    # On recupere l'iterateur du premier y.
    iter, top = textbuffer.get_line_at_y(premier_y)

    # On recupere la position de chaque iterateur et on l'ajoute 
    # a la liste. On s'arrete apres dernier_y.
    nombre,taille = 0,0
    while not iter.is_end():
        y, hauteur = textbuffer.get_line_yrange(iter)
        coords_buffer.append(y)
        num_ligne = iter.get_line()
        numeros.append(num_ligne)
        nombre += 1
        # suite nouvelle étude je le remet
        if (y + hauteur) >= dernier_y:
            break        
        iter.forward_line()
    return nombre

def on_text_view_draw(text_view, cairo_context):
    text_buffer = text_view.get_buffer()
    start,end = text_buffer.get_bounds()
    text = text_buffer.get_text(start,end,False)

    nlines = text.count("\n") + 1


    #collect size of visible part of window
    rectangle_visible = text_view.get_visible_rect()
    premier_y = rectangle_visible.y
    dernier_y = premier_y +rectangle_visible.height 

    # collect numeros & pixels to be display 
    numeros = []
    pixels = []    
    nombre = recup_lignes(text_view,premier_y, dernier_y, pixels, numeros)
    # Affichage de numéros internationalises !
    layout = text_view.create_pango_layout("")

    pos_horizontal = 2
    for i in range(nombre):
        x, pos = text_view.buffer_to_window_coords(Gtk.TextWindowType.RIGHT, 0, pixels[i])
        chaine = "<span weight='bold' foreground='red'>%d </span>" % numeros[i]
        layout.set_markup(chaine,len(chaine))
        # met les numeros dans la zone texte
        Gtk.render_layout(text_view.get_style_context(), cairo_context, pos_horizontal, pos, layout)

long_text = u"0 Your Answer\n\
 1 Thanks for contributing an answer to Stack Overflow!\n\
 2   Please be sure to answer the question. Provide details and share your research!\n\
 3\n\
 4 But avoid …\n\
 5\n\
 6  Asking for help, clarification, or responding to other answers.\n\
 7  Making statements based on opinion; back them up with references or personal experience.\n\
 8\n\
 9To learn more, see our tips on writing great answers.\n\
10 Your Answer\n\
11Thanks for contributing an answer to Stack Overflow!\n\
12    Please be sure to answer the question. Provide details and share your research!\n\
13 \n\
14 But avoid …\n\
15\n\
16   Asking for help, clarification, or responding to other answers.\n\
17    Making statements based on opinion; back them up with references or personal experience.\n\
18 \n\
19 To learn more, see our tips on writing great answers.\n"

tooltip = u'textview avec numérotation de ligne\n\
<b>Warning</b> la numérotation ne fonctionne correctement que si on ne fait pas circuler le scrolling'


text_view = Gtk.TextView()    
text_view.set_border_window_size(Gtk.TextWindowType.RIGHT, 54)
text_view.set_border_window_size(Gtk.TextWindowType.LEFT,54)
text_view.set_editable(True)
text_view.modify_base(Gtk.StateType.NORMAL, Gdk.color_parse('light green'))# non OK change marg like in gtk2
text_view.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse('orange'))#background text OK
text_view.modify_fg(Gtk.StateType.NORMAL, Gdk.color_parse('green'))# modifie la couleur du texte OK
text_view.modify_font( Pango.FontDescription('Arial normal 10'))# OK
text_view.set_tooltip_markup(tooltip)
text_view.connect("draw", on_text_view_draw)

text_buffer = text_view.get_buffer()
text_buffer.insert_at_cursor(long_text) #sympath pour inserer la où est le curseur mais pas nécessaire ici
#text_buffer.insert_markup(long_text)

scroller = Gtk.ScrolledWindow()
scroller.set_hexpand(True)
scroller.set_vexpand(True)
scroller.set_shadow_type(Gtk.ShadowType.IN)
scroller.add(text_view)

window = Gtk.Window()
window.connect("delete-event", Gtk.main_quit)
window.set_position(Gtk.WindowPosition.CENTER)
window.set_default_size(300, 200)
window.set_border_width(12)
window.add(scroller)
window.show_all()

demo = False
if demo:
    for i in dir(Gtk.TextBuffer):
        print i
Gtk.main()

@tclsteixeira
Copy link

Gtk 3 - Doesn't work. No numbers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment