gpt4 book ai didi

python - 文本小部件 Tkinter 中的行号间距

转载 作者:行者123 更新时间:2023-11-30 23:04:42 25 4
gpt4 key购买 nike

我按照 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()

我想要什么:

运行代码生成的结果如下所示:

enter image description here

我使用 ms-paint 编辑了这张图片以显示红色标记。红色的行号是我想要的。可以看出, Canvas 上的编号也包括空格,我想修改代码,使空白或空白处没有行号。

所以我想实现两个目标:

1).按照给出的红色标记数字的方式进行行编号。

2).如果可能的话,进行此更改后,我还想从 Canvas 中提取该文本小部件的任何给定字符串的行号。

我尝试过的

我正在尝试比较两个文件并在缺少点的地方引入空行。在继续之前,我需要实现一种算法,该算法可以从分配行号中排除空白(大多数编辑器都会发生这种情况)。到目前为止,我正在尝试,但找不到如何在上面的代码中实现这一点。

最佳答案

希望 Bryan Oakley 能够看到您的问题并发布 Eloquent 解决方案。但与此同时,这种有点古怪的方法却有效。 :)

在每次重绘时,我们都会获取小部件的当前文本内容,并构建一个字典,该字典使用每个非空行的索引作为字典中的键,该字典保存我们想要的实际行号。

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, 行,它将在每次重绘时打印每个非空行及其编号。您可能不希望这样,但它应该可以帮助您弄清楚如何提取给定行的行号。

关于python - 文本小部件 Tkinter 中的行号间距,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33565639/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com