在GUI中打印列表中的Python字符串
我有一个这样的列表:
list = ['one', 'two', 'three', 'four']
而且这个列表里的内容每10分钟就会变化一次(记住这一点)。
我需要一个带背景图片的图形界面(gui),可以在上面显示列表中的每一项。我本来可以用
for item in list:
print item
来做到这一点,我试过用tkinter,但在mainloop()的时候遇到了一些问题。当我执行
for item in list:
root = Tk()
canvas = Canvas(width = 300, height = 200, bg = 'yellow')
canvas.pack(expand = YES, fill = BOTH)
gif1 = PhotoImage(file = 'myImage.gif')
canvas.create_image(0, 0, image = gif1, anchor = NW)
# print item from my list
w = Label(root, text=item)
w.pack()
root.mainloop()
时,tkinter的图形界面会显示出来,但只显示“one”(我列表中的第一个项目)。当我关闭这个界面时,又会弹出一个窗口,显示“two”,再关闭那个窗口后就会显示“three”……最后是“four”。这很正常,因为我一直在一个循环里,每处理一个列表项就生成一个新的界面。
我的问题是:我该如何更新这个图形界面?因为我的列表内容每10分钟就会变化一次。我需要遍历我的列表,把所有的项目都显示在一个图形界面窗口里。10分钟后,我想再遍历一次列表,更新界面。
我该怎么做呢?
3 个回答
0
这里有一种使用两个线程的方法,这在你需要进行长时间计算或处理阻塞输入输出时很有用。你可以设置一个队列,用来在主界面线程和“供给”线程之间进行通信。你可以在一个函数中从队列中读取数据,这个函数会在主循环中定期被调用,使用 root.after() 来实现。所有的 TK 方法都必须在调用 root.mainloop() 的线程中执行(否则你的程序可能会崩溃)。
import threading
from Tkinter import Tk, Canvas, Label
import Queue
import time
from itertools import cycle
# Feeder thread puts one word in the queue every second
source_iter = cycle(['one', 'two', 'three', 'four', 'five', 'six'])
queue = Queue.Queue()
def source():
for item in source_iter:
queue.put(item)
time.sleep(1.)
source_thread = threading.Thread(target=source)
source_thread.setDaemon(True)
source_thread.start()
# Main thread reads the queue every 250ms
root = Tk()
w = Label(root, text='')
w.pack()
def update_gui():
try:
text = queue.get_nowait()
w.config(text=text)
except Queue.Empty:
pass
root.after(250, update_gui)
update_gui()
root.mainloop()
1
你的代码基本上是对的,只是你开始循环的地方导致了多个窗口的出现。如果你把循环放在标签部分之前,就能把列表中的所有四个项目都打印出来。现在的情况是这样的:
from tkinter import *
list=["one","two","three","four"]
root = Tk()
canvas = Canvas(width = 300, height = 200, bg = 'yellow')
canvas.pack(expand = YES, fill = BOTH)
# print item from my list
for item in list:
w = Label(root, text=item)
w.pack()
root.mainloop()
1
你看到四个窗口是因为你在循环里定义了主循环和其他所有内容。你可以试试下面这个方法:
root = Tk()
canvas = Canvas(width = 300, height = 200, bg = 'yellow')
canvas.pack(expand = YES, fill = BOTH)
gif1 = PhotoImage(file = 'myImage.gif')
canvas.create_image(0, 0, image=gif1, anchor = NW)
item=" ".join(list)
w = Label(root, text=item)
w.pack()
root.mainloop()
这个方法会把列表中的所有项目打印成一行。接下来的步骤是,当列表发生变化时,重新绘制主窗口。我对Tk不太熟悉,所以帮不了你。
可以试试这个链接,学习如何正确使用Tk。