1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | # # ################################################## ######## Please Don't Remove Author Name ######### ############### Thanks ########################### ################################################## # # __author__='''
###################################################### By ######################################################
Suraj Singh surajsinghbisht054@gmail.com http://www.bitforestinfo.com/
###################################################### ''' from Graphics import Tkinter as tk
class LineNumberCanvas(tk.Canvas): def __init__(self, *args, **kwargs): tk.Canvas.__init__(self, *args, **kwargs) self.text_widget = None self.breakpoints = []
def connect(self,text_widget): self.text_widget = text_widget
def re_render(self): """Re-render the line canvas""" self.delete('all') # To prevent drawing over the previous canvas
temp = self.text_widget.index("@0,0") while True : dline= self.text_widget.dlineinfo(temp) if dline is None: break y = dline[1] x = dline[0] linenum = str(temp).split(".")[0]
id = self.create_text(2,y,anchor="nw", text=linenum)
if int(linenum) in self.breakpoints: x1,y1,x2,y2 = self.bbox(id) self.create_oval(x1,y1,x2,y2,fill='red') self.tag_raise(id)
temp = self.text_widget.index("%s+1line" % temp)
def get_breakpoint_number(self,event): if self.find_withtag('current'): i = self.find_withtag('current')[0] linenum = int(self.itemcget(i,'text'))
if linenum in self.breakpoints: self.breakpoints.remove(linenum) else: self.breakpoints.append(linenum) self.re_render()
class LineMain: def __init__(self, text): self.text = text self.master = text.master self.mechanise() self._set_() self.binding_keys()
def mechanise(self): self.text.tk.eval(''' proc widget_interceptor {widget command args} {
set orig_call [uplevel [linsert $args 0 $command]]
if { ([lindex $args 0] == "insert") || ([lindex $args 0] == "delete") || ([lindex $args 0] == "replace") || ([lrange $args 0 2] == {mark set insert}) || ([lrange $args 0 1] == {xview moveto}) || ([lrange $args 0 1] == {xview scroll}) || ([lrange $args 0 1] == {yview moveto}) || ([lrange $args 0 1] == {yview scroll})} {
event generate $widget <<Changed>> }
#return original command return $orig_call } ''') self.text.tk.eval(''' rename {widget} new interp alias {{}} ::{widget} {{}} widget_interceptor {widget} new '''.format(widget=str(self.text))) return
def binding_keys(self): for key in ['<Down>','<Up>',"<<Changed>>","<Configure>"]: self.text.bind(key, self.changed) self.linenumbers.bind('<Button-1>',self.linenumbers.get_breakpoint_number) return
def changed(self, event): self.linenumbers.re_render() #print "render" return
def _set_(self): self.linenumbers = LineNumberCanvas(self.master, width=30) self.linenumbers.connect(self.text) self.linenumbers.pack(side="left", fill="y") return
if __name__ == '__main__': root = tk.Tk() l=tk.Text(root) LineMain(l) l.pack() root.mainloop()
|