You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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()

关键修改说明

  1. 替换定时方案:用Tkinter的after()替代schedule和外部死循环,after()会在事件循环中定时触发任务,不会阻塞窗口响应。
  2. 复用窗口组件:窗口root和Labellabel仅初始化一次,后续通过label.config()更新文本,避免重复创建窗口导致的阻塞。
  3. 修复类方法错误:修正原代码中read_temp里未加self.的readTempSensor调用问题。
  4. 优化数据处理:从传感器返回的字符串中提取纯数值计算最大值,避免字符串比较的错误。

内容的提问来源于stack exchange,提问作者Vitalij Sawizki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 14:30:43