我正在使用Kvaser Leaf Professional,并试图通过Python从摩托车中读取can总线数据,以便能够使用这些数据查看值的变化以及哪些值保持不变。
目前,我很难在tkinter上显示数据,并在每次数据再次读取/更新之后更新数据,因为它每隔几微秒就会改变一次。使用.after()的正常方式似乎不能100%起作用,或者我只是做错了什么。或者有比tkinter更好的显示更新数据的方法?
另一个问题是,当我显示tkinter时,它使用root.mailoop()运行窗口,当这种情况发生时,它进入主循环,不退出并运行程序的其余部分,也无法更新显示在窗口上的现有数据。有没有办法绕过root.mainloop()呢?
任何洞察力都将是有用的和/或我在代码中所犯的小错误。我是在两天前才开始使用Python的,现在我还在学习很多东西,还不知道所有的输入和输出。提前谢谢你。
到目前为止,这是我的全部计划:
import keyboard
import time
import sys
import tkinter as tk
import binascii
from canlib import canlib, Frame
from canlib.canlib import ChannelData
root = tk.Tk()
def setUpChannel(channel,
openFlags=canlib.canOPEN_ACCEPT_VIRTUAL,
bitrate=canlib.canBITRATE_500K,
bitrateFlags=canlib.canDRIVER_NORMAL):
ch = canlib.openChannel(channel, openFlags)
print("Using channel: %s, EAN: %s" % (ChannelData(channel).channel_name,
ChannelData(channel).card_upc_no)
)
ch.setBusOutputControl(bitrateFlags)
ch.setBusParams(bitrate)
ch.busOn()
return ch
def tearDownChannel(ch):
ch.busOff()
ch.close()
def text(t):
tx = binascii.hexlify(t).decode('utf-8')
n = 2
txt = [tx[i:i+n] for i in range(0, len(tx), n)]
return txt
def counter():
while True:
try:
cnt = 1
frame = ch0.read()
firstID = frame.id
while True:
frame = ch0.read()
cnt += 1
if frame.id == firstID:
break
pass
except (canlib.canNoMsg):
break
except (canlib.canError):
print("Rerun")
pass
return cnt
print("canlib version:", canlib.dllversion())
ch0 = setUpChannel(channel=0)
ch1 = setUpChannel(channel=1)
frame = Frame(id_=100, data=[1, 2, 3, 4], flags=canlib.canMSG_EXT)
ch1.write(frame)
print(frame)
cnt = counter()
print("Counter: %d" %(cnt))
time.sleep(1)
while True:
while True:
try:
show = ""
i = 1
while i <= cnt:
frame = ch0.read()
show = show +("%s\t%s\n" %(frame.id, text(frame.data)))
i += 1
print(show)
T = tk.Text(root, height=6, width=80)
T.config(state="normal")
T.insert(tk.INSERT, show)
T.pack()
root.mainloop()
break
except (canlib.canNoMsg) as ex:
pass
except (canlib.canError) as ex:
print(ex)
pass
tearDownChannel(ch0)
tearDownChannel(ch1)您可以根据需要编辑我的代码,如果我能够更好地实现代码,它将有很大帮助。
发布于 2019-12-12 15:19:02
你不需要使用多线程或任何复杂的东西。只需使用widget.after()方法,该方法在所需的时间之后调用您选择的另一个函数/方法。在下面的例子中,时间是1秒-> 1000毫秒。只需在call循环之前调用类,它就会开始工作。
class UI:
def __init__(self, parent):
# variable storing time
self.seconds = 0
# label displaying time
self.label.configure(text="%i s" % self.seconds)
# start the timer
self.label.after(1000, self.refresh_label)
def refresh_label(self):
#refresh the content of the label every second
# increment the time
self.seconds += 1
# display the new time
self.label.configure(text="%i s" % self.seconds)
# request tkinter to call self.refresh after 1s (the delay is given in ms)
self.label.after(1000, self.refresh_label)https://stackoverflow.com/questions/59304444
复制相似问题