【发布时间】:2020-02-08 12:23:31
【问题描述】:
我目前正在尝试编写由 Raspberry Pi 控制的机械臂。
到目前为止一切正常,除了一件事,我已经用谷歌搜索并尝试了很多小时,但找不到有效的解决方案。
对于机器人手臂的运动,必须使用螺纹“同时”运行所有电机(工作正常)。
我遇到的问题是,我需要更新一个标签,该标签在轴(电机)完成运动后立即显示当前角度,但其他电机仍在运行(线程)。
经过大量研究,我认为我通过使用队列和 Tkinter 后置方法找到了解决方案。但它仍然不起作用,因为标签文本只有在所有线程终止后才会更新。
我编写了一个示例代码,我想在其中获取电机“一”的标签更新,这将在电机“二”(500 次迭代)之前完成其 for 循环(100 次迭代)。我预计一旦电机 1 达到目标,而电机 2 仍在运行,标签就会更新。
但是虽然我使用了 after-method,但它仍然要等到电机 2 完成后才更新标签。
希望你能帮助我!
from tkinter import *
import threading
import time
from queue import *
class StepperMotors:
def __init__(self, root):
self.root = root
self.start_btn = Button(root, text="Start", command=lambda:self.start_movement())
self.start_btn.config(width = 10)
self.start_btn.grid(row=1,column=1)
self.label_one = Label(root, text='')
self.label_one.config(width = 10)
self.label_one.grid(row=2, column=1)
self.label_two = Label(root, text='')
self.label_two.config(width = 10)
self.label_two.grid(row=3, column=1)
def start_movement(self):
self.thread_queue = Queue()
self.root.after(100, self.wait_for_finish)
thread_one = threading.Thread(target=self.motor_actuation, args=(1,100))
thread_two = threading.Thread(target=self.motor_actuation, args=(2,500))
thread_one.start()
thread_two.start()
thread_one.join()
thread_two.join()
def motor_actuation(self, motor, iterations):
for i in range(iterations):
i = i+1
update_text = str(motor) + " " + str(i) + "\n"
print(update_text)
time.sleep(0.01)
self.thread_queue.put(update_text)
def wait_for_finish(self):
try:
self.text = self.thread_queue.get()
self.label_one.config(text=self.text)
except self.thread_queue.empty():
self.root.after(100, self.wait_for_finish)
if __name__ == "__main__":
root = Tk()
root.title("test")
stepper = StepperMotors(root)
root.mainloop()
【问题讨论】:
-
你不应该调用
.join(),因为它会阻塞 tkinter 主循环。此外,wait_for_finish()函数中的逻辑将在第一个电机完成时自行停止调度。 -
谢谢!但是 .join() 方法对于程序的另一部分非常重要(此处未显示)。是否有另一种方法可以在线程处理期间以某种方式使用 join 和更新 tkinter?
-
@timosmd 你对
def wait_for_finish的实现是错误的,与use threads to preventing main event loop from “freezing”比较 -
谢谢,我去看看!
-
“另一种使用 join AND update tkinter 的方式”:不,这是矛盾的。阅读Tkinter understanding mainloop
标签: python multithreading tkinter label