Python 使用 tkinter 同时循环两个循环
Posted
技术标签:
【中文标题】Python 使用 tkinter 同时循环两个循环【英文标题】:Python two loops simultaneously with tkinter 【发布时间】:2021-04-09 10:34:16 【问题描述】:我有两个框架的 Tkinter GUI 应用程序。我想要做的是同时运行两个无限循环。 而一个循环可以从另一个循环中获取数据。
我有 main.py
class Main(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
container = tk.Frame(self)
.....
.....
app = Main()
app.mainloop()
然后两个帧首先是 startPage.py,其中只有一个按钮重定向到experimentPage.py。 最后一个重要的框架。 ExperimentPage.py 这两个循环在哪里。
class experimentPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
// ButtonX that start two loops //
....
....
def loop1(self)
def loop2(self) // Getting data from loop1
我要做的基本上是同时运行loop1和loop2,而loop2可以从loop1获取数据。现在我不确定如何实现这一点,我所有的尝试都失败了。
如果我理解正确,我必须使用 asyncio 修改 main.py mainloop。并用 asyncio 修改实验页面。使用async def loop1(self)
就可以了。但无论我尝试什么都以错误结束。
编辑 1 - 在这我只有一个循环。但是在那个循环中,我从眼球追踪器获取数据,将它们绘制在屏幕上并进行一些计算。问题是它从我实际查看的位置和绘制的内容中得到了一些延迟。这就是为什么我想要两个循环。一个用于来自眼球追踪器的实时数据。还有一个用于绘图和计算的东西。
编辑 2 - 问题是我不知道如何正确编辑 mainloop 以运行异步任务,因为我发现的所有内容也都与线程有关。我尝试了 app.asyncio.mainloop() 之类的东西,它以 AttributeError 之类的错误结束:'_tkinter.tkapp' object has no attribute 'asyncio'
我只使用 python 几天,所以我可能会遗漏一些基本的东西。
【问题讨论】:
您能否更具体地了解循环,而不仅仅是 tkinter。为什么需要两个循环?他们在做什么单循环不会做的事情。 您要解决的问题是什么?您的问题暗示了一种有缺陷的方法。 感谢您的反应,我将它们添加为对我的问题的编辑。 为什么不想使用线程?这不是显而易见的解决方案吗? @wuerfelfreak 我认为异步方法比线程更容易,这就是我决定使用异步的原因。但我可能会切换到线程感谢您的评论。 【参考方案1】:可以这样使用:
def loop2(self):
while !self.stopSignal:
#do stuff here
def start_loops():
self.stopSignal = False
thread = threading.Thread(target=loop2, args=(self,))
thread.start()
loop1(self)
self.stopSignal = True
thread.join()
【讨论】:
【参考方案2】:您可以使用计时器来实现这一点。
在 Tkinter 中,你可以使用tk.after
from tkinter import *
import cv2
from PIL import Image,ImageTk
def take_snapshot():
print("some one like it")
def video_loop():
success, img = camera.read() # read image with camera
if success:
# cv2.waitKey(1) # this line is not necessary in Tkinter
cv2image = cv2.cvtColor(img, cv2.COLOR_BGR2RGBA) #convert color from BGR to RGBA
current_image = Image.fromarray(cv2image) #convert to Image for Tkinter
imgtk = ImageTk.PhotoImage(image=current_image)
panel.imgtk = imgtk
panel.config(image=imgtk)
root.after(1, video_loop)
camera = cv2.VideoCapture(0) #camera
root = Tk()
root.title("opencv + tkinter")
#root.protocol('WM_DELETE_WINDOW', detector)
panel = Label(root) # initialize image panel
panel.pack(padx=10, pady=10)
root.config(cursor="arrow")
btn = Button(root, text="Like!", command=take_snapshot)
btn.pack(fill="both", expand=True, padx=10, pady=10)
video_loop()
root.mainloop()
# before quit the program, release all the resources
camera.release()
cv2.destroyAllWindows()
【讨论】:
以上是关于Python 使用 tkinter 同时循环两个循环的主要内容,如果未能解决你的问题,请参考以下文章