我正在按照Bryan Oakley的代码here向文本小部件添加行号功能。我在该文本框中插入自己的XML文件。该文件列在下面:
myfile.xml中
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<p1:sample1 xmlns:p1="http://www.example.org/eHorizon">
<p1:time nTimestamp="5">
<p1:location hours = "1" path = '1'>
<p1:feature color="6" type="a">560</p1:feature>
<p1:feature color="2" type="a">564</p1:feature>
<p1:feature color="3" type="b">570</p1:feature>
<p1:feature color="4" type="c">570</p1:feature>
</p1:location>
</p1:time>
<p1:time nTimestamp="6">
<p1:location hours = "1" path = '1'>
<p1:feature color="2" type="a">564</p1:feature>
<p1:feature color="3" type="b">570</p1:feature>
<p1:feature color="4" type="c">570</p1:feature>
</p1:location>
</p1:time>
</p1:sample1>
myCode.py
import Tkinter as tk
class TextLineNumbers(tk.Canvas):
def __init__(self, *args, **kwargs):
tk.Canvas.__init__(self, *args, **kwargs)
self.textwidget = None
def attach(self, text_widget):
self.textwidget = text_widget
def redraw(self, *args):
'''redraw line numbers'''
self.delete("all")
i = self.textwidget.index("@0,0")
while True :
dline= self.textwidget.dlineinfo(i)
if dline is None: break
y = dline[1]
linenum = str(i).split(".")[0]
self.create_text(2,y,anchor="nw", text=linenum)
i = self.textwidget.index("%s+1line" % i)
class CustomText(tk.Text):
def __init__(self, *args, **kwargs):
tk.Text.__init__(self, *args, **kwargs)
self.tk.eval('''
proc widget_proxy {widget widget_command args} {
# call the real tk widget command with the real args
set result [uplevel [linsert $args 0 $widget_command]]
# generate the event for certain types of commands
if {([lindex $args 0] in {insert replace delete}) ||
([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 <<Change>> -when tail
}
# return the result from the real widget command
return $result
}
''')
self.tk.eval('''
rename {widget} _{widget}
interp alias {{}} ::{widget} {{}} widget_proxy {widget} _{widget}
'''.format(widget=str(self)))
class Example(tk.Frame):
def __init__(self, *args, **kwargs):
tk.Frame.__init__(self, *args, **kwargs)
self.text = CustomText(self)
self.vsb = tk.Scrollbar(orient="vertical", command=self.text.yview)
self.text.configure(yscrollcommand=self.vsb.set)
self.text.tag_configure("bigfont", font=("Helvetica", "24", "bold"))
self.linenumbers = TextLineNumbers(self, width=30)
self.linenumbers.attach(self.text)
self.vsb.pack(side="right", fill="y")
self.linenumbers.pack(side="left", fill="y")
self.text.pack(side="right", fill="both", expand=True)
self.text.bind("<<Change>>", self._on_change)
self.text.bind("<Configure>", self._on_change)
file = open('C:/your/file/location/myFile.xml')
self.text.insert("end", file.read())
def _on_change(self, event):
self.linenumbers.redraw()
if __name__ == "__main__":
root = tk.Tk()
Example(root).pack(side="top", fill="both", expand=True)
root.mainloop()
我想要的是什么:
运行代码时生成的结果如下所示:
我使用ms-paint编辑了这张照片以显示红色标记。用红色编号是我想要的。可以看出画布上的编号也包含空格,我想修改代码,使得空格或空格上没有行号。
所以我想实现两个目标:
1)。按照红色标记的方式跟随行号。
2)。在可能的情况下进行此更改之后,我还想从canvas获取该文本小部件的任何给定字符串的行号。
我尝试了什么
我正在尝试比较两个文件,并在缺少点的地方引入空行。在我继续之前,我需要实现一个算法,该算法可以从分配行号中排除空白空间(大多数编辑器都会这样做)。到目前为止,我正在玩,但无法找到如何在上面的代码中实现这一点。
答案 0 :(得分:3)
希望Bryan Oakley会看到你的问题并发布一个雄辩的解决方案。但与此同时,这种有点黑客的方法也起作用。 :)
在每次重绘时,我们获取窗口小部件的当前文本内容,并构建一个字典,该字典使用每个非空行的索引作为字典中的键,该字典包含我们想要的实际行号。
def redraw(self, *args):
'''redraw line numbers'''
self.delete("all")
# Build dict to convert line index to line number
linenums = {}
num = 1
contents = self.textwidget.get("1.0", tk.END)
for i, line in enumerate(contents.splitlines(), 1):
i = str(i) + '.0'
# Only increment line number if the line's not blank
linetext = self.textwidget.get(i, "%s+1line" % i)
if linetext.strip():
linenums[i] = str(num)
#print num, linetext,
num += 1
i = self.textwidget.index("@0,0")
while True :
dline = self.textwidget.dlineinfo(i)
if dline is None:
break
linenum = linenums.get(i)
if linenum is not None:
y = dline[1]
self.create_text(2,y,anchor="nw", text=linenum)
i = self.textwidget.index("%s+1line" % i)
如果您取消评论#print num, linetext,
行,则会在每次重绘时打印每个非空行及其编号。您可能不希望如此,但它应该可以帮助您弄清楚如何提取给定行的行号。