I am trying to create an instrumental cluster using the OBDII and the tkinter as the GUI. The problem is that, the GUI is non responsive and the draw time is very bad as I have only 1 thread. I am new to python and the OOP concepts and is the reason I am not sure how to proceed here. This is what I want to do, I want two threads one for the drawing while other too process the data. Also can I use multiple threads to draw the objects too? Any help is appreciated
import tkinter as tk
from PIL import ImageTk
from PIL import Image
import datetime
import obd
class SimpleApp(object):
def __init__(self, master, **kwargs):
self.master = master
self.canvas = tk.Canvas(width=1400, height=800)
self.canvas.pack()
self.update = self.draw().__next__
master.after(1, self.update)
def draw(self):
image_bk = Image.open("img/1.png")
image = Image.open("img/2.png")
image1 = Image.open("img/3.png")
image_prnd = Image.open("img/4.png")
angle = 2 # 0 -> 270
angle1 = 0 # 0 -> 89
Speed = 0
RPM = 0
Fuel = 0
Temp = 0
Time = ' '
tkimage_bk = ImageTk.PhotoImage(image_bk)
self.canvas.create_image(700, 400, image=tkimage_bk)
self.canvas.create_text(100, 770, fill="white", font="BatmanForeverOutline 20 bold", text=" 70 F")
tkimage_prnd = ImageTk.PhotoImage(image_prnd)
while True:
tkimage = ImageTk.PhotoImage(image.rotate(angle))
tkimage1 = ImageTk.PhotoImage(image1.rotate(angle1))
canvas_obj = self.canvas.create_image(690, 400, image=tkimage)
canvas_obj1 = self.canvas.create_image(700, 400, image=tkimage1)
self.canvas.create_image(700, 400, image=tkimage_prnd)
self.canvas.create_text(700, 350, fill="white", font="BatmanForeverAlternate 20 bold ", text="MPH")
self.canvas.create_text(700, 525, fill="white", font="BatmanForeverAlternate 20 bold ", text="RPM")
self.canvas.create_text(700, 655, fill="white", font="BatmanForeverOutline 22 bold ", text="P R N S")
self.canvas.create_text(760, 655, fill='white', font="BatmanForeverAlternate 45 ", text="D")
speed = self.canvas.create_text(700, 290, fill="white", font="Beyond 80 ", text=str(Speed))
rpm = self.canvas.create_text(700, 465, fill="white", font="Beyond 65 ", text=str(RPM))
temp = self.canvas.create_text(1250, 240, fill="white", font="BatmanForeverOutline 22 ",text=str(Temp) + " F")
fuel = self.canvas.create_text(1250, 470, fill='white', font="BatmanForeverOutline 22 ", text=str(Fuel) + " %")
time1 = self.canvas.create_text(1000, 770, fill="white", font="BatmanForeverOutline 20 bold", text=datetime.datetime.now().strftime("%a, %d %B"))
time2 = self.canvas.create_text(1250, 770, fill="white", font="BatmanForeverOutline 20 bold", text=datetime.datetime.now().strftime("%I : %M : %S"))
run_time = self.canvas.create_text(500, 770, fill="white", font="BatmanForeverOutline 20 bold",text=str(Time))
self.master.after_idle(self.update)
yield
self.canvas.delete(time1)
self.canvas.delete(canvas_obj)
self.canvas.delete(canvas_obj1)
self.canvas.delete(time1)
self.canvas.delete(time2)
self.canvas.delete(run_time)
self.canvas.delete(temp)
self.canvas.delete(fuel)
self.canvas.delete(speed)
self.canvas.delete(rpm)
RPM = str(connection.query(cmd).value)
RPM = RPM.split()
RPM = int(RPM[ 0 ])
Speed = str(connection.query(cmd1).value)
Speed = Speed.split()
Speed = int(Speed[ 0 ] / 1.60934)
Temp = str(connection.query(cmd2).value)
Temp = float(Temp.split()[ 0 ])
Time = str(connection.query(cmd3).value)
Time = int(Time.split()[ 0 ])
Fuel = str(connection.query(cmd4).value)
Fuel = int(float(Fuel.split()[ 0 ]))
if (Speed > -1 and Speed < 21):
angle = (Speed * 0.75)
angle = 360 - angle
else:
angle = ((20 * 0.75) + ((Speed - 20) * 1.5))
angle = 360 - angle
if (RPM > -1 and RPM < 1000):
angle1 = 0.016 * RPM
else:
angle1 = 16 + (RPM - 1000) * 0.0296
connection = obd.OBD()
cmd = obd.commands.RPM
cmd1 = obd.commands.SPEED
cmd2 = obd.commands.COOLANT_TEMP
cmd3 = obd.commands.RUN_TIME
cmd4 = obd.commands.FUEL_LEVEL
root = tk.Tk()
app = SimpleApp(root)
root.mainloop()
As far as I remember, tkinter incorrectly processes changes to the gui not from the main thread. But you can perform calculations in other threads and transfer to the main one.
Pay attention to the tkinter after method. Using it, you can check the data in streams at some intervals.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.