如何让Tkinter窗口持续显示定时任务获取的温度数据?
解决Tkinter窗口持续显示并定时更新温度数据的问题
你的核心问题是同时混用了Tkinter事件循环和schedule死循环,且每次调用max_temp都会新建窗口并执行mainloop,导致代码阻塞,必须销毁窗口才能继续。要实现窗口持续打开并仅更新数据,需放弃schedule和外部死循环,改用Tkinter原生的after()方法处理定时任务,同时只创建一次窗口和Label组件。
修改后的完整代码
import getpass import pandas as pd import time import tkinter as tk username = getpass.getuser() desktop_path = f"/home/{username}/Desktop" # 传感器路径 sensor = '/sys/bus/w1/devices/28-00000007c9b5/w1_slave' sensor_2 = '/sys/bus/w1/devices/28-000000084de0/w1_slave' class csv_file: def __init__(self, filename, path): self.filename = filename self.path = path self.tempCelsius = 0.0 self.sensorName = "" def readTempSensor(self, sensorName): """从系统总线读取DS18B20传感器数据""" self.sensorName = sensorName with open(self.sensorName, 'r') as f: lines = f.readlines() return lines def read_temp(self, sensorName): lines = self.readTempSensor(sensorName) # 等待传感器返回有效数据 while lines[0].strip()[-3:] != 'YES': time.sleep(0.2) lines = self.readTempSensor(sensorName) temperaturStr = lines[1].find('t=') if temperaturStr != -1: tempData = lines[1][temperaturStr + 2:] self.tempCelsius = float(tempData) / 1000.0 return f"{self.tempCelsius}, {self.sensorName[20:35]}" def open_file(self): """将温度数据写入CSV""" current_time = time.strftime("%H:%M:%S") data = pd.DataFrame({ 'temp': [self.tempCelsius], 'time': [current_time], 'sensor_id': [self.sensorName[20:35]] }) print(f"{self.sensorName[20:35]} --> Temp C° {self.tempCelsius} Time --> {current_time}") data.to_csv(f"{self.path}/{self.filename}", mode='a', header=False, index=False, sep=' ') # 初始化传感器实例 one_sensor = csv_file("first_sensor", desktop_path) two_sensor = csv_file("second_sensor", desktop_path) def update_temperature(): """定时更新温度数据并刷新Label""" # 获取两个传感器的温度 temp1 = one_sensor.read_temp(sensor) temp2 = two_sensor.read_temp(sensor_2) # 保存数据到CSV one_sensor.open_file() two_sensor.open_file() # 提取温度数值计算最大值 temp_values = [float(temp.split(',')[0]) for temp in [temp1, temp2]] max_temp = max(temp_values) # 更新Label文本(仅修改内容,不重建组件) label.config(text=f"Maximale Temperatur = {max_temp:.2f} °C") # 2秒后再次执行该函数,实现定时更新 root.after(2000, update_temperature) # 创建主窗口(仅初始化一次) root = tk.Tk() root.geometry("640x640") # 创建Label组件(仅初始化一次) label = tk.Label(root, text="Maximale Temperatur = -- °C", font=('Arial', 16)) label.pack(pady=20) # 启动第一次更新 update_temperature() # 启动Tkinter事件循环 root.mainloop()
关键修改说明
- 替换定时方案:用Tkinter的
after()替代schedule和外部死循环,after()会在事件循环中定时触发任务,不会阻塞窗口响应。 - 复用窗口组件:窗口
root和Labellabel仅初始化一次,后续通过label.config()更新文本,避免重复创建窗口导致的阻塞。 - 修复类方法错误:修正原代码中
read_temp里未加self.的readTempSensor调用问题。 - 优化数据处理:从传感器返回的字符串中提取纯数值计算最大值,避免字符串比较的错误。
内容的提问来源于stack exchange,提问作者Vitalij Sawizki
相关产品推荐
相关产品推荐

