Tkinter-更新坐标或移动具有可变值的形状



我正在使用Tkinter可视化传感器数据。我正在读取串行数据,我想用它在屏幕上移动一个正方形。

from tkinter import Tk, Canvas
import tkinter
import serial
#GUI
root = Tk()
c = Canvas(root, width=1000, height=50)
c.configure(bg='grey', highlightthickness=0)
#Position Parameters
posX=10
posY=20
lenght=10
subject = c.create_rectangle(posX, posY, posX+lenght, posY+lenght, outline='black', fill='black')
#Serial Data Read
ser = serial.Serial('COM5', baudrate=9600, timeout=0.2)  # open serial port
print(ser.name)                                          # check which port was really used
#Failed Live Visual
while True:
while (ser.inWaiting()==0):
pass
dataPacket=ser.readline()
dataPacket=str(dataPacket, 'utf-8')                 #Incoming data from arduino into string
dataPacket=int(dataPacket.strip(' rn'))           #Formatting
posX=dataPacket
c.coords(subject, posX, posY, posX+lenght, posY+lenght)
c.pack()
root.mainloop()

我的问题是:Tkinter将显示但不会更新正方形的位置。我尝试过不同的方法,比如使用c.move((setter,以及创建一个函数并用root.after((命令调用它,但似乎都不起作用。我认为这不应该这么难,所以这就是我问的原因。

感谢您抽出时间!

使用mainloop()的方式是错误的——它通常在tkinter应用程序中只调用一次,因为它是驱动整个GUI的循环,而整个GUI是由事件驱动的。

在这种情况下,绕过这一限制的一种方法是使用其通用的after()小部件方法来安排对输入串行端口的定期检查。

为了做到这一点,我对您的代码进行了更改,包括添加一个Start按钮来启动定期轮询过程。显然,我无法完全测试它,但它应该能给你一个整体的想法。

import tkinter as tk
import serial
#GUI
root = tk.Tk()
start_btn = tk.Button(root, text='Start')
start_btn.pack(anchor=tk.NW)
c = tk.Canvas(root, width=1000, height=50)
c.configure(bg='grey', highlightthickness=0)
c.pack()  # ADDED
#Position Parameters
posX=10
posY=20
lenght=10
subject = c.create_rectangle(posX, posY, posX+lenght, posY+lenght, outline='black', fill='black')
#Serial Data Read
ser = serial.Serial('COM5', baudrate=9600, timeout=0.2)
print(ser.name)  # check which port was really used
def check_data():
if ser.inWaiting():
dataPacket=ser.readline()
dataPacket=str(dataPacket, 'utf-8')  #Incoming data from arduino into string
dataPacket=int(dataPacket.strip(' rn'))  #Formatting
posX=dataPacket
c.coords(subject, posX, posY, posX+lenght, posY+lenght)
root.after(250, check_data)  # Check again in 250 ms.
start_btn.config(command=check_data)
root.mainloop()

最新更新