Python 如何每半秒钟更新tkinter文本标签?如何避免.main循环,以便程序的其余部分可以执行?
我正在使用Kvaser Leaf Professional,并试图通过Python编码从摩托车读取can总线数据,以便能够使用数据查看值在哪里变化,哪些值保持不变 目前,我正努力在Python 如何每半秒钟更新tkinter文本标签?如何避免.main循环,以便程序的其余部分可以执行?,python,tkinter,Python,Tkinter,我正在使用Kvaser Leaf Professional,并试图通过Python编码从摩托车读取can总线数据,以便能够使用数据查看值在哪里变化,哪些值保持不变 目前,我正努力在tkinter上显示数据,并在每次读取/更新数据后进行更新,因为数据每隔几微秒就会发生变化。正常使用.after()的方法似乎无法100%正常工作,或者我只是做错了什么。还是有比显示更新数据更好的方法 我遇到的另一个问题是,当我显示tkinter时,它使用root.mailoop()来运行窗口,当这种情况发生时,它进入
tkinter
上显示数据,并在每次读取/更新数据后进行更新,因为数据每隔几微秒就会发生变化。正常使用.after()
的方法似乎无法100%正常工作,或者我只是做错了什么。还是有比显示更新数据更好的方法
我遇到的另一个问题是,当我显示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)
导入键盘
导入时间
导入系统
将tkinter作为tk导入
导入binascii
从canlib导入canlib,帧
从canlib.canlib导入通道数据
root=tk.tk()
def设置通道(通道,
openFlags=canlib.canOPEN\u ACCEPT\u VIRTUAL,
比特率=canlib.canBITRATE_500K,
bitrateFlags=canlib.canDRIVER\u正常值):
ch=canlib.openChannel(通道,openFlags)
打印(“使用频道:%s,EAN:%s”%(频道数据(频道)。频道名称,
信道数据(信道)。卡(upc\U编号)
)
ch.setBusOutputControl(比特率标志)
ch.setBusParams(比特率)
布森先生()
返回ch
def拆卸通道(ch):
布索夫先生()
第三章结束()
定义文本(t):
tx=binascii.hexlify(t).解码('utf-8')
n=2
txt=[tx[i:i+n]表示范围内的i(0,len(tx),n)]
返回文本
def计数器():
尽管如此:
尝试:
cnt=1
frame=ch0.read()
firstID=frame.id
尽管如此:
frame=ch0.read()
cnt+=1
如果frame.id==firstID:
打破
通过
除(canlib.canNoMsg)外:
打破
除了(canlib.canError):
打印(“重新运行”)
通过
返回cnt
打印(“canlib版本:”,canlib.dllversion())
ch0=设置通道(通道=0)
ch1=设置通道(通道=1)
frame=frame(id=100,data=[1,2,3,4],flags=canlib.canMSG\u EXT)
ch1.写入(帧)
打印(帧)
cnt=计数器()
打印(“计数器:%d”%(cnt))
时间。睡眠(1)
尽管如此:
尽管如此:
尝试:
show=“”
i=1
而我你不需要使用多线程或任何复杂的东西。只需使用widget.after()方法,该方法在所需时间后调用您选择的另一个函数/方法。在下面的例子中,时间是1秒->1000毫秒。只需在主循环之前调用该类,它就会开始工作
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)
阅读后,您可能会通过使用多个线程来改进。请看我对这个问题的回答。注意:我怀疑每隔几微秒更新tkinter GUI的可能性,因此您可能能做的最好的事情是以更慢的速度。我尝试实现您的示例,但现在它抛出了更多错误,我对Python的了解还不够,无法完全理解我做错了什么。你能告诉我如何用我已有的代码实现它吗?我将显示代码移动到一个函数,并在主循环中调用它,这是我应该通过.after()
调用的函数吗?