如果我正确理解了问题(而且很有可能我没有……),最简单的解决方案可能是使用文本小部件。
使第一行是一系列与行长度相同的空格。使用几个交替的标签(例如:“偶数”和“奇数”)为每个字符赋予一种交替的颜色,使它们彼此突出。第二行是标题,任何剩余的行都是几行样本数据。
然后,在第一行设置绑定,以在用户单击字符时将空格转换为“x”。如果他们单击“x”,则将其转换回空格。然后他们可以去点击作为每列开头的字符。用户完成后,您可以获得文本小部件的第一行,并且每列都会有一个“x”。然后,您只需要一个小函数将其转换为您需要的任何格式。
它看起来大致像这样(尽管颜色显然与本网站上显示的颜色不同)
x x x ...
SequenSack and PaFull Name****************************]JOB...
000001T1 P1 Sample A Sample ...
这里有一个快速的技巧来说明一般的想法。这有点草率,但我认为它说明了这项技术。运行它时,单击第一行中的一个区域以设置或清除标记。这将导致标题以每个标记的交替颜色突出显示。
import sys
import Tkinter as tk
import tkFont
class SampleApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
header = "SequenSack and PaFull Name****************************]JOB TITLE****************]HOSP NAME******************************]Delivery Address***********************]Alternate 1 Address********************]Calculated Text**********************************]POSTNET Bar"
sample = "000001T1 P1 Sample A Sample 123 Any Street Anytown 12345-6789 12345678900"
widget = DelimiterWidget(self, header, sample)
hsb = tk.Scrollbar(orient="horizontal", command=widget.xview)
widget.configure(xscrollcommand=hsb.set)
hsb.pack(side="bottom", fill="x")
widget.pack(side="top", fill="x")
class DelimiterWidget(tk.Text):
def __init__(self, parent, header, samplerow):
fixedFont = tkFont.nametofont("TkFixedFont")
tk.Text.__init__(self, parent, wrap="none", height=3, font=fixedFont)
self.configure(cursor="left_ptr")
self.tag_configure("header", background="gray")
self.tag_configure("even", background="#ffffff")
self.tag_configure("header_even", background="bisque")
self.tag_configure("header_odd", background="lightblue")
self.tag_configure("odd", background="#eeeeee")
markers = " "*len(header)
for i in range(len(header)):
tag = "even" if i%2==0 else "odd"
self.insert("end", " ", (tag,))
self.insert("end", "\n")
self.insert("end", header+"\n", "header")
self.insert("end", samplerow, "sample")
self.configure(state="disabled")
self.bind("<1>", self.on_click)
self.bind("<Double-1>", self.on_click)
self.bind("<Triple-1>", self.on_click)
def on_click(self, event):
'''Handle a click on a marker'''
index = self.index("@%s,%s" % (event.x, event.y))
current = self.get(index)
self.configure(state="normal")
self.delete(index)
(line, column) = index.split(".")
tag = "even" if int(column)%2 == 0 else "odd"
char = " " if current == "x" else "x"
self.insert(index, char, tag)
self.configure(state="disabled")
self.highlight_header()
return "break"
def highlight_header(self):
'''Highlight the header based on marker positions'''
self.tag_remove("header_even", 1.0, "end")
self.tag_remove("header_odd", 1.0, "end")
markers = self.get(1.0, "1.0 lineend")
i = 0
start = "2.0"
tag = "header_even"
while True:
try:
i = markers.index("x", i+1)
end = "2.%s" % i
self.tag_add(tag, start, end)
start = self.index(end)
tag = "header_even" if tag == "header_odd" else "header_odd"
except ValueError:
break
if __name__ == "__main__":
app = SampleApp()
app.mainloop()