方法后的 Tkinter 小部件
Tkinter widget after method
我还没有找到可以回答我问题的话题,所以:
我的 GUI 包含 3 个独立的 "windows"(框架?)作为 classes:TextInput、TextOutput 和 Statistic。出于性能原因,我只 运行 Statistic.mainloop() 但其他 class 也出现了。
我想让我的 TextInput class 做的是
遍历包含字符串的列表并将它们插入文本小部件 "self.ref_text"。
class TextInput(tk.Frame):
LARGE_FONT = ("Arial Bold ", 18)
SMALL_FONT = ("Arial", 16)
BGC = '#CDCDC1'
FG = ['#000000', '#f44242']
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
# print('415 TextInput instance: ', type(self))
self.controller = controller
self.reference = [] # some strings in here
self.createText()
def createText(self):
self.ref_text = tk.Text(self, height=30, width=100, font=TextInput.SMALL_FONT)
self.ref_text.config(background=TextInput.BGC)
self.ref_text.grid(column=0, columnspan=4, row=1, padx=5, sticky="W")
def display_ref(self, line):
print('line: ', line)
self.ref_text.insert('end', line)
def read_ref(self):
for line in self.reference:
self.ref_text.insert('end', line)
self.ref_text.after(1500, self.read_ref)
after() 方法插入 "self.reference" 的所有字符串,而不是预期的 FOR 循环。此外,整个 TextInput 应用程序似乎倾斜(很多递归?)
在另一个版本中,我尝试调用
self.ref_text.after(1500, self.display_ref, line)
1500 毫秒后再次将所有文本放入小部件中。
我做错了什么?
是不是我只有运行
的问题
Statistik.mainloop()
在底部而不是 TextInput.mainloop()。
感谢您的帮助
至于最小的例子:
import tkinter as tk
class Interface(tk.Tk):
def __init__(self, name, page, *kwargs):
tk.Tk.__init__(self, name, *kwargs)
container = tk.Frame(self)
container.pack(side="top", fill="both", expand=True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
container.master.title(name)
self.frames = {}
self.windows = {}
self.windows[name] = page
self.window = page(container, self)
self.frames[name] = self.window
self.window.grid(row=0, column=0, sticky='nsew')
self.show_window(name)
def show_window(self, cont):
window = self.frames[cont]
window.tkraise()
class TextInput(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.reference = ['a is a sentence', 'b follows a', 'c closes the session']
self.createText()
self.read = True
self.read_ref()
def stop_read(self):
self.read = False
def createText(self):
self.ref_text = tk.Text(self, height=30, width=80,)
self.ref_text.grid(column=0, row=1, columnspan=3, padx=5, sticky="W")
def display_ref(self, line):
print('line: ', line)
self.ref_text.insert('end', line)
def read_ref(self):
'''
the goal is to loop through self.reference line by line
with a 1500 ms pause inbetween
'''
for line in self.reference:
if self.read:
self.ref_text.insert('end', line + '\n')
self.ref_text.after(1500, self.read_ref)
else:
return
class Statistik(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
'''does some other stuff'''
textinput_instance = Interface('TextInput', TextInput)
statistik_instance = Interface('Statistik', Statistik)
statistik_instance.mainloop()
如果您的目标是遍历列表,以 1500 毫秒的间隔显示每一行,最简单的方法是使用一个函数进行一次迭代,然后使用 after
重复自身
可能是这样的:
def read_ref(self, lines):
# remove one item from the list
line = lines.pop(0)
# insert it
self.ref_text.insert("end", line + "\n")
# run again in 1500ms if there's still more work to do
if lines:
self.after(1500, self.read_ref, lines)
然后,恰好调用此函数一次以启动该过程:
self.read_ref(self, self.reference)
如果你想停止它,你可以在你的函数中检查一个标志:
def read_ref(self):
...
if self.reference and not self.stop:
self.after(1500, self.read_ref)
以上代码缓慢地从 self.reference
中删除项目。如果您不希望发生这种情况,请在开始时传递 self.reference
的副本,以便该函数将从原始数据的副本中删除项目。
self.read_ref(self, self.reference[:])
我还没有找到可以回答我问题的话题,所以:
我的 GUI 包含 3 个独立的 "windows"(框架?)作为 classes:TextInput、TextOutput 和 Statistic。出于性能原因,我只 运行 Statistic.mainloop() 但其他 class 也出现了。
我想让我的 TextInput class 做的是 遍历包含字符串的列表并将它们插入文本小部件 "self.ref_text"。
class TextInput(tk.Frame):
LARGE_FONT = ("Arial Bold ", 18)
SMALL_FONT = ("Arial", 16)
BGC = '#CDCDC1'
FG = ['#000000', '#f44242']
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
# print('415 TextInput instance: ', type(self))
self.controller = controller
self.reference = [] # some strings in here
self.createText()
def createText(self):
self.ref_text = tk.Text(self, height=30, width=100, font=TextInput.SMALL_FONT)
self.ref_text.config(background=TextInput.BGC)
self.ref_text.grid(column=0, columnspan=4, row=1, padx=5, sticky="W")
def display_ref(self, line):
print('line: ', line)
self.ref_text.insert('end', line)
def read_ref(self):
for line in self.reference:
self.ref_text.insert('end', line)
self.ref_text.after(1500, self.read_ref)
after() 方法插入 "self.reference" 的所有字符串,而不是预期的 FOR 循环。此外,整个 TextInput 应用程序似乎倾斜(很多递归?) 在另一个版本中,我尝试调用
self.ref_text.after(1500, self.display_ref, line)
1500 毫秒后再次将所有文本放入小部件中。
我做错了什么? 是不是我只有运行
的问题Statistik.mainloop()
在底部而不是 TextInput.mainloop()。 感谢您的帮助
至于最小的例子:
import tkinter as tk
class Interface(tk.Tk):
def __init__(self, name, page, *kwargs):
tk.Tk.__init__(self, name, *kwargs)
container = tk.Frame(self)
container.pack(side="top", fill="both", expand=True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
container.master.title(name)
self.frames = {}
self.windows = {}
self.windows[name] = page
self.window = page(container, self)
self.frames[name] = self.window
self.window.grid(row=0, column=0, sticky='nsew')
self.show_window(name)
def show_window(self, cont):
window = self.frames[cont]
window.tkraise()
class TextInput(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.reference = ['a is a sentence', 'b follows a', 'c closes the session']
self.createText()
self.read = True
self.read_ref()
def stop_read(self):
self.read = False
def createText(self):
self.ref_text = tk.Text(self, height=30, width=80,)
self.ref_text.grid(column=0, row=1, columnspan=3, padx=5, sticky="W")
def display_ref(self, line):
print('line: ', line)
self.ref_text.insert('end', line)
def read_ref(self):
'''
the goal is to loop through self.reference line by line
with a 1500 ms pause inbetween
'''
for line in self.reference:
if self.read:
self.ref_text.insert('end', line + '\n')
self.ref_text.after(1500, self.read_ref)
else:
return
class Statistik(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
'''does some other stuff'''
textinput_instance = Interface('TextInput', TextInput)
statistik_instance = Interface('Statistik', Statistik)
statistik_instance.mainloop()
如果您的目标是遍历列表,以 1500 毫秒的间隔显示每一行,最简单的方法是使用一个函数进行一次迭代,然后使用 after
可能是这样的:
def read_ref(self, lines):
# remove one item from the list
line = lines.pop(0)
# insert it
self.ref_text.insert("end", line + "\n")
# run again in 1500ms if there's still more work to do
if lines:
self.after(1500, self.read_ref, lines)
然后,恰好调用此函数一次以启动该过程:
self.read_ref(self, self.reference)
如果你想停止它,你可以在你的函数中检查一个标志:
def read_ref(self):
...
if self.reference and not self.stop:
self.after(1500, self.read_ref)
以上代码缓慢地从 self.reference
中删除项目。如果您不希望发生这种情况,请在开始时传递 self.reference
的副本,以便该函数将从原始数据的副本中删除项目。
self.read_ref(self, self.reference[:])