如上例所示,滚动速度太快时,左列的Label对象或右列的Entry对象不会混合显示。
如果我单击滚动条并快速拖动,它看起来可能像这样糟糕。如果我使用鼠标滚轮缓慢滚动,通常很好,尽管有时无论滚动速度如何,都会错过一行。作为参考,它似乎总是与缓慢滚动时未显示的同一行。
来回更改选项卡会使所有内容再次正确绘制。在Linux上,一切正常。但这也需要在Windows上工作。
不确定是否重要,但是每一行都是Canvas内部的Frame中的Label和Entry,画布与滚动条一起位于Frame内部。每个顶部框架都是笔记本中的“页面”,以提供顶部显示的标签。
最后是一些问题。我可以添加一个按钮来强制重绘而不破坏并重新创建它吗?也许我可以在创建这些对象时添加一些内容,以迫使它们在移动时重绘?
根据要求提供示例代码:
#!/usr/bin/env python3
from tkinter import *
from tkinter import ttk
from tkinter.scrolledtext import ScrolledText
class WriteableEntry(Label):
def __init__(self, name, value, *args, **kwargs):
#~ self.ip = ip
#~ self.ping_results = []
super(WriteableEntry, self).__init__(*args, **kwargs)
self.label = name
self.init_value = value
self.written_value = ''
self.field_name = Label(self, justify="left", text=name, width=25)
self.field_value = Entry(self, justify='left', width=60)
self.field_value.insert(END, value)
self.field_name.pack(side=LEFT)
self.field_value.pack(side=LEFT)
class InfoFrame(Frame):
def __init__(self, *args, **kwargs):
super(InfoFrame, self).__init__(*args, **kwargs)
self.nb_frame = Frame(self, height=300, width=730)
self.nb_frame.pack_propagate(False)
self.nb = ttk.Notebook(self.nb_frame)
self.nb.pressed_index = None
filler = {}
for x in range(0, 3):
for y in ('a', 'b', 'c', 'd', 'e', 'f', 'g'):
filler.update({"out%d_%s" % (x, y):"nada"})
self.example_dict = {'A':filler, 'B':filler, 'C':filler}
print("E_D:\n", self.example_dict)
for page in sorted(self.example_dict):
print("page:\t", page)
entry_count = len(self.example_dict[page])
# # ## Make new_page to put in nb
new_page = Frame(self.nb)
new_page.pack(fill=BOTH, expand=True)
# # ## Make canvas to put in that new_page
canvas = Canvas(new_page)
scroll = Scrollbar(new_page, command=canvas.yview)
## Orig *27
canvas.config(yscrollcommand=scroll.set, scrollregion=(0,120,120,entry_count * 35))
canvas.pack(side=LEFT, fill=BOTH, expand=True)
scroll.pack(side=RIGHT, fill=Y)
# # ## Make a frame to put in that canvas
canvas_frame = Frame(canvas, bg='white', width=50, height=50)
## Orig +12 *10
canvas.create_window(345, (entry_count + 12) * 13, window=canvas_frame)
for value in sorted(self.example_dict[page]):
print("value:\t", value)
writeable_entry = WriteableEntry(value, self.example_dict[page][value], master=canvas_frame)
writeable_entry.pack(side=TOP)
self.nb.add(new_page, text=page)
self.nb.pack(side=TOP, expand=True, fill="both")
self.nb_frame.pack(side=RIGHT, expand=True, fill=BOTH)
class IPLabel(LabelFrame):
def __init__(self, *args, **kwargs):
super(IPLabel, self).__init__(*args, **kwargs)
self.info_frame = InfoFrame(master=self)
self.info_frame.grid(row=1, columnspan=2, sticky=E + W)
class AvailableApplication(Frame):
def __init__(self, master):
super(AvailableApplication, self).__init__(master)
#~ self.ips = ips
self.grid()
self.grid_propagate(True)
self.ip_widgets = []
self.createWidgets()
def createWidgets(self):
self.ip_frame = Frame(self)
self.ip_widgets = []
ip_widget = IPLabel(master=self.ip_frame)
ip_widget.grid(row=0, column=1, columnspan=4, sticky=E + W)
self.ip_widgets.append(ip_widget)
self.ip_frame.grid(row=1, column=0, columnspan=8)
self.ip_frame.grid_propagate(True)
if __name__ == "__main__":
root = Tk()
root.title("Example Script")
app = AvailableApplication(root)
app.mainloop()
root.destroy()
答案 0 :(得分:1)
主要问题是WriteableEntry
。它不是tk.Label
。您不能拥有tk.Label
的子窗口小部件(tk.Entry
和tk.Label
)。您也为此工作使用了错误的布局管理器。可能还因为错误的子窗口小部件使用。您依靠pack
管理器的包装行为。别。使用grid()
管理器。
由于某些原因,标签C
不可见,但这是另一个问题。
使用Ctrl-Tab
,我发现有第三个标签,但标签文本为空字符串。使用
self.nb.add(new_page, text="P"+page)
使其更清晰可见。我不知道为什么选项卡名称“ C” 对于tkinter具有特殊含义
杀死应用程序和窗口的唯一可能方法是使用Close
按钮。那么,为什么要破坏根窗口?它已经被破坏了。
#!/usr/bin/env python3
from tkinter import *
from tkinter import ttk
from tkinter.scrolledtext import ScrolledText
class WriteableEntry(object):
def __init__(self, name, value, *args, **kwargs):
#~ self.ip = ip
#~ self.ping_results = []
#super(WriteableEntry, self).__init__(*args, **kwargs)
master = kwargs['master']
row = kwargs['row']
self.label = name
self.init_value = value
self.written_value = ''
self.field_name = Label(master, justify="left", text=name, width=25)
self.field_value = Entry(master, justify='left', width=60)
self.field_value.insert(END, value)
self.field_name.grid(row=row, column=0)
self.field_value.grid(row=row, column=1)
class InfoFrame(Frame):
def __init__(self, *args, **kwargs):
super(InfoFrame, self).__init__(*args, **kwargs)
self.nb_frame = Frame(self, height=300, width=730)
self.nb_frame.pack_propagate(False)
self.nb = ttk.Notebook(self.nb_frame)
self.nb.pressed_index = None
filler = {}
for x in range(0, 3):
for y in ('a', 'b', 'c', 'd', 'e', 'f', 'g'):
filler.update({"out%d_%s" % (x, y):"nada"})
self.example_dict = {'A':filler, 'B':filler, 'C':filler}
print("E_D:\n", self.example_dict)
for page in sorted(self.example_dict):
print("page:\t", page)
entry_count = len(self.example_dict[page])
# # ## Make new_page to put in nb
new_page = Frame(self.nb)
new_page.pack(fill=BOTH, expand=True)
# # ## Make canvas to put in that new_page
canvas = Canvas(new_page)
scroll = Scrollbar(new_page, command=canvas.yview)
## Orig *27
canvas.config(yscrollcommand=scroll.set, scrollregion=(0,120,120,entry_count * 35))
canvas.pack(side=LEFT, fill=BOTH, expand=True)
scroll.pack(side=RIGHT, fill=Y)
# # ## Make a frame to put in that canvas
canvas_frame = Frame(canvas, bg='white', width=50, height=50)
## Orig +12 *10
canvas.create_window(345, (entry_count + 12) * 13, window=canvas_frame)
for row, value in enumerate(sorted(self.example_dict[page])):
print("value:\t", value)
writeable_entry = WriteableEntry(value, self.example_dict[page][value], master=canvas_frame, row=row)
#writeable_entry.pack(side=TOP)
self.nb.add(new_page, text="P"+page)
self.nb.pack(side=TOP, expand=True, fill="both")
self.nb_frame.pack(side=RIGHT, expand=True, fill=BOTH)
class IPLabel(LabelFrame):
def __init__(self, *args, **kwargs):
super(IPLabel, self).__init__(*args, **kwargs)
self.info_frame = InfoFrame(master=self)
self.info_frame.grid(row=1, columnspan=2, sticky=E + W)
class AvailableApplication(Frame):
def __init__(self, master):
super(AvailableApplication, self).__init__(master)
#~ self.ips = ips
self.grid()
self.grid_propagate(True)
self.ip_widgets = []
self.createWidgets()
def createWidgets(self):
self.ip_frame = Frame(self)
self.ip_widgets = []
ip_widget = IPLabel(master=self.ip_frame)
ip_widget.grid(row=0, column=1, columnspan=4, sticky=E + W)
self.ip_widgets.append(ip_widget)
self.ip_frame.grid(row=1, column=0, columnspan=8)
self.ip_frame.grid_propagate(True)
if __name__ == "__main__":
root = Tk()
root.title("Example Script")
app = AvailableApplication(root)
app.mainloop()
#root.destroy()