python - 在 Tkinter 中更新文本小部件中的值
问题描述
我需要在不关闭该窗口的情况下在 10 秒后更新同一 Tkinter 窗口中的一些其他数据的值。我试过使用after
Tkinter 的方法,但它不适合我的目的。depth_chart
是一个需要在此窗口中显示的具有 3 列和多行的数组。
from tkinter import *
root = Tk()
root.title("Depth Ladder")
height = len(depth_chart)
width = len(depth_chart[0])
Label(root, text = "Bid Quantity").grid(row = 0, column = 0)
Label(root, text = "Price").grid(row = 0, column = 1)
Label(root, text = "Ask Quantity").grid(row = 0, column = 2)
for i in range(height): #Rows
for j in range(width): #Columns
a= str(depth_chart[i][j])
b = Text(root,height =1)
if a != "None":
b.insert(INSERT,a)
if j ==0:
b.config(bg="green",fg = "white",relief = RIDGE,width =8)
elif j==1:
b.config(background="black",fg = "white",relief = RIDGE,width =12)
elif j ==2:
b.config(background="red",fg = "white",relief = RIDGE,width =8)
b.grid(row=i+1, column=j)
root.mainloop()
解决方案
您可以首先使用空小部件创建网格Text
并将它们保留在 2D 列表中。
稍后您可以运行从小部件中删除旧数据Text
并放入新数据的功能。最后它应该after()
在 10 秒后再次运行。
问题可以生成获取新数据的代码,depth_chart
但您没有显示这部分,所以我模拟更改depth_chart
在此示例中,我创建随机数据并每 1 秒更新一次。
import tkinter as tk # PEP8: `import *` is not preferred
import random # simulate changes in data
# --- functions ---
def fill_text():
global depth_chart
for y, row in enumerate(depth_chart):
for x, item in enumerate(row):
# remove previous text
all_text[y][x].delete('0.1', 'end')
# add new text
if item is not None:
all_text[y][x].insert('insert', item)
# simulate changes in data
depth_chart = [[random.randint(0, 10) for x in range(3)] for y in range(10)]
# fill it again after 1s (1000ms)
root.after(1000, fill_text)
# --- main ---
# simulate changes in data
depth_chart = [[random.randint(0, 10) for x in range(3)] for y in range(10)]
root = tk.Tk()
root.title("Depth Ladder")
tk.Label(root, text="Bid Quantity").grid(row=0, column=0) # PEP8: without spaces around `=`
tk.Label(root, text="Price").grid(row=0, column=1)
tk.Label(root, text="Ask Quantity").grid(row=0, column=2)
# create grid with empty widgets `Text` and remember them on 2D list
all_text = []
for y, row in enumerate(depth_chart, 1):
row_text = []
for x, item in enumerate(row):
text = tk.Text(root, height=1)
text.grid(row=y, column=x)
if x == 0:
text.config(bg="green", fg="white", relief='ridge', width=8)
elif x == 1:
text.config(bg="black", fg="white", relief='ridge', width=12)
elif x == 2:
text.config(bg="red", fg="white", relief='ridge', width=8)
row_text.append(text)
all_text.append(row_text)
# fill it first time
fill_text()
root.mainloop()
编辑:
如果您每 10 秒有不同的行数,depth_chart
那么从网格中删除所有行并再次创建新小部件会更容易Text
- 然后您可以在Text
创建时直接添加值。
它有一个问题 -当所有小部件都被移除时它会闪烁。
import tkinter as tk # PEP8: `import *` is not preferred
import random # simulate changes in data
# --- functions ---
def fill_text():
global depth_chart
global all_text
# simulate changes in data
number_of_rows = random.randint(5, 20)
depth_chart = [[random.randint(0, 10) for x in range(3)] for y in range(number_of_rows)]
# delete old text widgets
for row in all_text:
for item in row:
item.destroy()
# clear list
all_text = []
# create grid with widgets `Text` and remember them on 2D list
for y, row in enumerate(depth_chart, 1):
row_text = []
for x, item in enumerate(row):
text = tk.Text(root, height=1)
text.grid(row=y, column=x)
if x == 0:
text.config(bg="green", fg="white", relief='ridge', width=8)
elif x == 1:
text.config(bg="black", fg="white", relief='ridge', width=12)
elif x == 2:
text.config(bg="red", fg="white", relief='ridge', width=8)
if item is not None:
text.insert('insert', item)
row_text.append(text)
all_text.append(row_text)
# fill it again after 1s (1000ms)
root.after(1000, fill_text)
# --- main ---
# place for all text widgets
all_text = []
root = tk.Tk()
root.title("Depth Ladder")
tk.Label(root, text="Bid Quantity").grid(row=0, column=0) # PEP8: without spaces around `=`
tk.Label(root, text="Price").grid(row=0, column=1)
tk.Label(root, text="Ask Quantity").grid(row=0, column=2)
# fill it first time
fill_text()
root.mainloop()
要解决闪烁问题,需要更复杂的代码来删除或添加只需要的行。
import tkinter as tk # PEP8: `import *` is not preferred
import random # simulate changes in data
# --- functions ---
def fill_text():
global depth_chart
global all_text
# simulate changes in data
number_of_rows = random.randint(5, 20)
depth_chart = [[random.randint(0, 10) for x in range(3)] for y in range(number_of_rows)]
# calculate how many rows add or delete
len_chart = len(depth_chart)
len_all = len(all_text)
diff = len_chart - len_all
#print(number_of_rows, diff)
if diff < 0:
# delete widgets
for row in all_text[diff:]:
for item in row:
item.destroy()
all_text = all_text[:diff]
elif diff > 0:
# add widgets
for y in range(len_all+1, len_chart+1):
text1 = tk.Text(root, height=1)
text1.grid(row=y, column=0)
text1.config(bg="green", fg="white", relief='ridge', width=8)
text2 = tk.Text(root, height=1)
text2.grid(row=y, column=1)
text2.config(bg="black", fg="white", relief='ridge', width=12)
text3 = tk.Text(root, height=1)
text3.grid(row=y, column=2)
text3.config(bg="red", fg="white", relief='ridge', width=8)
all_text.append([text1, text2, text3])
# put values in `Text`
for y, row in enumerate(depth_chart):
for x, item in enumerate(row):
# remove previous text
all_text[y][x].delete('0.1', 'end')
# add new text
if item is not None:
all_text[y][x].insert('insert', item)
# fill it again after 1s (1000ms)
root.after(1000, fill_text)
# --- main ---
# place for all text widgets
all_text = []
root = tk.Tk()
root.title("Depth Ladder")
tk.Label(root, text="Bid Quantity").grid(row=0, column=0) # PEP8: without spaces around `=`
tk.Label(root, text="Price").grid(row=0, column=1)
tk.Label(root, text="Ask Quantity").grid(row=0, column=2)
# fill it first time
fill_text()
root.mainloop()
推荐阅读
- azure - JSON解析日志条目
- angular - 原理图工作流失败
- javascript - 为什么我的 json.dumps 没有将报价值转换为我的浏览器?
- regex - 在谷歌表格中运行用于条件格式的自定义公式仅格式化“应用于范围”中的第一个单元格
- unity3d - UNITY2D:在具有相同标签和相同图层的两个对象之间进行选择
- ios - 在 iOS 上通过 Spotify App Remote 的 SPTSession 进行身份验证时获取一个奇怪的刷新令牌
- elasticsearch - Elasticsearch / Kibana - 如何通过特定标识符获取日志的时间点快照
- css - 即使在正文中设置了绝对大小,移动 Firefox 上的字体大小与移动 Chrome 不同
- react-native - 如何在 React Native 中获取设备令牌?
- git - Android-studio 更改列表功能如何在 git 的幕后工作