【发布时间】:2020-11-17 08:36:36
【问题描述】:
我在 Tkinter 中显示来自电池管理系统 (EMUS BMS) 的消息内容时出现问题。我使用 Raspberry-Pi 4 通过 Serial 收集数据,然后通过 elif 条件解析数据并将数据记录在 U 盘上。
import tkinter as tk
from tkinter import messagebox
import tkinter.font as font
import serial
import time
from USB_Status import usb_status
import threading, queue
class Application(tk.Frame):
def __init__(self, master=None):
super().__init__(master)
self.master = master
self.pack()
self.create_widgets(master)
def create_widgets(self, master):
def button_emus():
anweisungs_label.config(text="EMUS BMS ausgewählt!", fg="green")
q = queue.Queue()
thread_ = threading.Thread(
target=connection_emus,
name="Emus-Thread",
args=[q],
daemon=True,
)
thread_.start()
thread_.join()
text_box.insert("end-1c", q.get())
emus_button.place(x = 420, y = 0, width=400, height=150)
text_box.place(x = 0, y = 160, width=2048, height=800)
def verarbeitung_emus(response, binary):
telegram=[]
#Battery Voltage Summary Sentence
if response[0:3] == "BV1":
number_of_cells = str(int(response[4:8], 16)) + " Zellen"
binary.write((number_of_cells + "\n").encode())
min_cell_voltage ="min. " + str((int(response[9:11], 16) + 200) * 0.01) + " V"
binary.write((min_cell_voltage + "\n").encode())
max_cell_voltage ="max. " + str((int(response[12:14], 16) + 200) * 0.01) + " V"
binary.write((max_cell_voltage + "\n").encode())
number = (int(response[15:17], 16) + 200) * 0.01
average_cell_voltage = "avrg. " + str(format(number, '.2f')) + " V"
binary.write((average_cell_voltage + "\n").encode())
telegram.extend([number_of_cells, min_cell_voltage, max_cell_voltage, average_cell_voltage])
# Battery Cell Module Temperature Summary Sentence
elif response[0:3] == "BT1":
number = int(response[9:11], 16) - 100
if number > 32767:
number = number - 65536
min_cell_module_temp = "min. " + str(number) + " °C"
binary.write((min_cell_module_temp + "\n").encode())
number = int(response[12:14], 16) - 100
if number > 32767:
number = number - 65536
max_cell_module_temp = "max. " + str(number) + " °C"
binary.write((max_cell_module_temp + "\n").encode())
number = int(response[15:17], 16) - 100
if number > 32767:
number = number - 65536
average_cell_module_temp = "avrg. " + str(format(number, '.2f')) + " °C"
binary.write((average_cell_module_temp + "\n").encode())
telegram.extend([min_cell_module_temp, max_cell_module_temp, average_cell_module_temp])
# Battery Balancing Rate Summary Sentence
elif response[0:3] == "BB1":
min_balancing_rate = "min. " + str(int(response[9:11], 16) * 100/255) + " %"
binary.write((min_balancing_rate + "\n").encode())
max_balancing_rate = "max. " + str(int(response[12:14], 16) * 100/255) + " %"
binary.write((max_balancing_rate + "\n").encode())
number = int(response[15:17], 16) * 100/255
average_balancing_rate = "avrg. " + str(format(number, '.2f')) + " %"
binary.write((average_balancing_rate + "\n").encode())
balancing_voltage_threshold = str((int(response[19:20], 16) + 200) * 0.01) + " V"
binary.write((balancing_voltage_threshold + "\n").encode())
telegram.extend([min_balancing_rate, max_balancing_rate, average_balancing_rate, balancing_voltage_threshold])
# “Current and Voltage” Sentence
elif response[0:3] == "CV1":
total_voltage = "overall " + str((int(response[4:12], 16) + 200) * 0.01) + " V"
binary.write((total_voltage + "\n").encode())
number = int(response[13:17], 16) * 0.1
if number > 32767:
number = number - 65536
current = "overall " + str(format(number, '.2f')) + " A"
binary.write((current + "\n").encode())
telegram.extend([total_voltage, current])
return telegram
def connection_emus(queue):
DEVICE = '/dev/ttyUSB0'
BAUD = 57600
ser = serial.Serial(DEVICE, BAUD)
binary = open('/media/data_logger/EMUS.bin', "ab")
try:
while True:
response = ser.readline()[:-2]
response = response.decode()
temp = verarbeitung_emus(response, binary)
if temp:
queue.put(temp)
while not queue.empty():
print(queue.get())
except KeyboardInterrupt:
usb_status()
ser.close()
binary.close()
root = tk.Tk()
app = Application(master=root)
app.mainloop()
我已经尝试过线程,在后台运行循环并访问它以读取值,但我从未使用过线程,除了启动线程之外,我无法访问任何东西。
编辑:线程现在与队列类一起工作,我可以显示来自守护进程的数据。但现在我想将数据传递给 tkinter 中的文本框对象。任何建议如何实现这一目标?
【问题讨论】:
-
应该是
threading.Thread(target=Emus)而不是threading.Thread(target=Emus()) -
是的,你是对的,我仍然无法访问数据
-
您在将数据放入队列后立即使用队列。
标签: python multithreading tkinter raspberry-pi