The way you're using mainloop()
is wrong — it's typically only called once in a tkinter
application because it is the loop that drives the whole GUI which is event-driven.
One way to work around that limitation in this case would be to use its universal after()
widget method to schedule periodic checks of the serial port for input.
I've made changes to your code to do this, including adding a Start button to initiate the periodic polling process. Obviously I couldn't fully test it, but it ought to give you the overall idea.
import tkinter as tkimport serial#GUIroot = 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 ParametersposX=10posY=20lenght=10subject = c.create_rectangle(posX, posY, posX+lenght, posY+lenght, outline='black', fill='black')#Serial Data Readser = serial.Serial('COM5', baudrate=9600, timeout=0.2)print(ser.name) # check which port was really useddef check_data(): if ser.inWaiting(): dataPacket=ser.readline() dataPacket=str(dataPacket, 'utf-8') #Incoming data from arduino into string dataPacket=int(dataPacket.strip(' \r\n')) #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()