Tkinter GUI能够更改独立连续过程的变量



我设计了一个船用发动机模拟器,它是一个使用某种协议发送一些串行数据的程序,称为";BlueVision";。数据基于标头、块编号、块类型、实际数据(索引(、校验和和和页脚进行编码。由于这样一个事实,如果你想更改实际数据中的值,那么校验和就会更改,我设计了一个在数据更改时使用正确校验和重新计算块的方法。我制作了一个GUI,允许我更改2个数据点的值,以便能够进行实时测试。问题是,我不知道如何正确使用线程子流程,并且窗口一直处于冻结状态。这个应用程序很好用,但效果很差,我一直在寻找类似的问题,确实找到了一些建议,但我还没能实现。有人能帮忙吗?附言:这个代码充其量也很尴尬——请不要评判——我知道我本可以做得更好——但这是我所能做的最好的事情。如果你没有程序写入的COM端口,你可能不清楚这个问题。

# Blue Vision is a MTU serial communication protocol - based on HEX values grouped in BLOCKS
import tkinter as tk
from tkinter import ttk
import time
import serial
def split_by_n(seq, n):
while seq:
yield seq[:n]
seq= seq[n:]
def after(self, ms, func=None, *args):
"""Call function once after given time.
MS specifies the time in milliseconds. FUNC gives the
function which shall be called. Additional parameters
are given as parameters to the function call.  Return
identifier to cancel scheduling with after_cancel."""
win = tk.Tk()
win.title("GUI - TEST VERSION")
win.geometry("750x250")

label = tk.Label(win, text = "Main Engine Overspeed")
label.pack()
v = tk.StringVar()
v.set('00')
c = tk.StringVar()
c.set("00")
def setText(word):
v.set(word)
a = ttk.Button(win, text ="01", command =lambda:setText("01"))
a.pack()
b = ttk.Button(win, text="00", command = lambda:setText("00"))
b.pack()
label1 = tk.Label(win, text ="Main Engine Speed")
label1.pack()
name_entry = tk.Entry(win, textvariable=c)
name_entry.pack()

def task():
MyVar = v.get()
priEngSp =c.get()
if len(priEngSp) == 0:
priEngSp = '00'

block_3 = 'FAF500030002000000290100000001000100000001000001000000000000000000000000000222AF5F'
block_4 = 'FAF500040003000001A000004650000047E00000000000000000000000000007EF4000083D6000000000000000000000000000000000000000000000012C000006D600000000000000000000278D00000000000000007FFFFFFF000000000001991500000000000000000016E36000000000000923D8000971F8000001F40000059F000026AC00002774000005800000251C00000580000027740000283C0000056200001D4C00001F400000061800000000000060FB00004650000036B000007D0000008CA0000006180000251C0000000000000000000000000000284800192D500017A6B00000051B0000251CFFFFFFA8000002580000044C000000FA0000000000000000000006770000CB200000D6D8000006770000CB200000D6D80000060600005DC000000000000027100000000000000000000000000000000000000000000003C2000061A8000000000000000000000000000000000000000000000000000000000000000000000000000000000000363300000EA6000249F0FFFFFB1E000F42400000000000000000000000000000000000000000000032D9AF5F'
block_5 = 'FAF5000500020000005600000000000000000000000000000000000000000000007F7F0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034AAF5F'
block_6 = 'FAF5000600020000003D00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000234AF5F'
block_7 = 'FAF5000700030000008C000006280000064A0000064A0000068D0000066B0000068D0000068D000006AE0000000000000000000006AE000006070000060700000607000005E5000005A2000006070000064A00000000000000000000062A000006AE000005A20000350EFFFFF07C00003CDEFFFFE8AC00000000000000000000000000000000000012DEAF5F'
block_8 = 'FAF50008000300000070000000000000112900000000000000000000059C000027740000283C000047E000000000000000000000000000000000000000000000000000000000000000007FFFFFFF7FFFFFFF0000055100002CEC0000000000000000000000000000000000000DD1AF5F'
block_9 = 'FAF50009000200000020000000000000000000000000000000000000021AAF5F'
block_10 = 'FAF5000A0002000000260000000000000000000000000000000000000000000000000221AF5F'
block_11 = 'FAF5000B0003000000EC00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002E9AF5F'
block_12 = 'FAF5000C000200000045000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000242AF5F'


block_2 = 'FAF50002000200000074010001000000000000000000000000000000000000000000007F0000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002E9AF5F'
checksum = hex(0x00)
block_2split = list(split_by_n(block_2,2))
block_2split[10] = MyVar.upper() #Overspeed Alarm Position
for i in range(len(block_2split)-6):
checksum = hex(int(checksum, 16) + int(block_2split[i], 16)) 
checksum_string = str(checksum)
checksum_actvalue = checksum_string[2:]
checksum_long = checksum_actvalue.rjust(8,'0').upper()
checksum_split = list(split_by_n(checksum_long,2))
block_2split[len(block_2split)-3] = checksum_split[3]
block_2split[len(block_2split)-4] = checksum_split[2]
block_2split[len(block_2split)-5] = checksum_split[1]
block_2split[len(block_2split)-6] = checksum_split[0]
Block_2Output = ''.join(str(item) for item in block_2split)
iEngineSpeed = int(priEngSp,10)
hEngineSpeed = hex(iEngineSpeed * 10)
sEngineSpeed = str(hEngineSpeed)[2:].upper()
while (len(sEngineSpeed)<8):
sEngineSpeed = '0' + sEngineSpeed

block_4split = list(split_by_n(block_4,4))
sEngineSpeed_split = list(split_by_n(sEngineSpeed,4))
block_4split[5] = sEngineSpeed_split[0]
block_4split[6] = sEngineSpeed_split[1]
Block_4joint = ''.join(str(item) for item in block_4split)
Block_4joint_sp = list(split_by_n(Block_4joint,2))
checksumb4 = hex(0x00)
for i in range(len(Block_4joint_sp)-6):
checksumb4 = hex(int(checksumb4, 16) + int(Block_4joint_sp[i], 16))
checksumb4_string = str(checksumb4)
checksumb4_actvalue = checksumb4_string[2:]
checksumb4_long = checksumb4_actvalue.rjust(8,'0').upper()
checksumb4_split = list(split_by_n(checksumb4_long,2))
Block_4joint_sp[len(Block_4joint_sp)-3] = checksumb4_split[3]
Block_4joint_sp[len(Block_4joint_sp)-4] = checksumb4_split[2]
Block_4joint_sp[len(Block_4joint_sp)-5] = checksumb4_split[1]
Block_4joint_sp[len(Block_4joint_sp)-6] = checksumb4_split[0]
Block_4Output = ''.join(str(item) for item in Block_4joint_sp)
blocks = [Block_2Output, block_3, Block_4Output, block_5, block_6, block_7, block_8, block_9, block_10, block_11, block_12]
with serial.Serial('COM5', '9600') as ser: #you might wanna comment this part out
for block in blocks:
print(block)
ser.write(bytes.fromhex(block.strip())) #you might wanna comment this part out
time.sleep(1)
win.after(200, task)
win.after(200, task)
win.mainloop()

为了避免冻结,其中一种方法是使用thread:

from threading import Thread
...
def task():
while True:
MyVar = v.get()
...
blocks = [Block_2Output, block_3, Block_4Output, block_5, block_6, block_7, block_8, block_9, block_10, block_11, block_12]
with serial.Serial('COM5', '9600') as ser: #you might wanna comment this part out
for block in blocks:
print(block)
ser.write(bytes.fromhex(block.strip())) #you might wanna comment this part out
time.sleep(1)
time.sleep(0.2)
# run task() in a thread
Thread(target=task, daemon=1).start()
win.mainloop()

最新更新