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

如何推送实时Pandas DataFrame并适配索引至Tkinter pandastable表格?

修复MQTT实时数据更新Pandastable表格的问题

我看了你这段代码,发现几个关键问题导致实时数据无法正常更新到表格里,还有一些逻辑上的疏漏,下面一步步帮你梳理和修复:


首先列出代码里的核心问题:

  • 没有初始化self.dataframe,导致update方法里访问self.dataframe.loc[len(self.dataframe)]时会报错
  • update方法定义了data参数,但启动线程时没传参,而且缺少循环获取MQTT数据的逻辑,现在只执行一次就结束
  • 构造实时DataFrame的方式错误:一维数组转DataFrame会把每个元素拆成单独一行,而不是一行完整数据
  • self.stop变量没有在初始化时定义,点击STOP按钮前访问会触发AttributeError
  • 缺少实时数据写入CSV的逻辑,无法实现历史数据的持久化
  • 注释掉了MQTT相关的导入,实际运行时需要恢复并处理数据接收

修复后的完整代码

import tkinter as tk
import pandas as pd
from pandastable import Table, TableModel
from threading import Thread
import time
import datetime
import numpy as np
# 恢复你的MQTT导入模块,比如:
# import mqtt_cloud_rec
# import tkintermqtt

# 确保CSV文件存在,不存在则创建空表(避免首次运行报错)
try:
    prevframe = pd.read_csv('mqttresult.csv')
except FileNotFoundError:
    # 初始化空DataFrame,和你的列名对应
    cols = ['Date','Time','power state','Motor state','Mode','Voltage','Current','Power Factor','KW','KWH','total Runtime']
    prevframe = pd.DataFrame(columns=cols)
    prevframe.to_csv('mqttresult.csv', index=False)

class TestApp(tk.Frame):
    """Basic test frame for the table"""
    def __init__(self, parent=None):
        self.parent = parent
        tk.Frame.__init__(self)
        self.main = self.master
        self.main.geometry('800x600+200+100')
        self.main.title('Mqtt Result Table')
        
        # 初始化停止标志和数据帧
        self.stop = False
        self.dataframe = prevframe.copy()  # 复制历史数据到实例变量
        
        f = tk.Frame(self.main)
        f.pack(fill=tk.BOTH,expand=1)
        
        # 创建表格并绑定数据帧
        self.table = Table(f, dataframe=self.dataframe, showtoolbar=True )
        self.table.show()
        
        # 按钮布局
        self.startbutton = tk.Button(self.main,text='START',command=self.start)
        self.startbutton.pack(side=tk.TOP,fill=tk.X)
        self.stopbutton = tk.Button(self.main,text='STOP',command=self.set_stop)
        self.stopbutton.pack(side=tk.TOP,fill=tk.X)

    def update_table(self):
        """循环获取MQTT数据并更新表格"""
        while not self.stop:
            # --- 这里替换成你实际获取MQTT数据的逻辑 ---
            # 示例:模拟MQTT接收的列表数据(和你的列对应,除了Date/Time)
            # 实际应该调用你的MQTT订阅方法,比如:
            # self.data = mqtt_cloud_rec.get_latest_data()
            self.data = ["ON", "RUNNING", "AUTO", "220V", "5A", "0.95", "1.1KW", "12.5KWH", "450H"]
            
            # 构造当前时间
            date_today = str(datetime.date.today())
            time_today = time.strftime("%H:%M:%S")
            
            # 构造完整的一行数据:时间 + Mqtt数据
            new_row = [date_today, time_today] + self.data
            
            # 将新行添加到DataFrame
            self.dataframe.loc[len(self.dataframe)] = new_row
            
            # 更新表格数据并刷新
            self.table.model.df = self.dataframe
            self.table.redraw()
            
            # 将更新后的数据写入CSV,持久化历史数据
            self.dataframe.to_csv('mqttresult.csv', index=False)
            
            # 控制更新频率,避免太频繁
            time.sleep(1)

    def start(self):
        """启动实时更新线程"""
        if not hasattr(self, 'update_thread') or not self.update_thread.is_alive():
            self.stop = False
            self.update_thread = Thread(target=self.update_table, daemon=True)
            self.update_thread.start()

    def set_stop(self):
        """停止实时更新"""
        self.stop = True

if __name__ == "__main__":
    app = TestApp()
    app.mainloop()

关键修改点说明:

  1. 初始化处理:

    • 增加了CSV文件不存在时的初始化逻辑,避免首次运行报错
    • 在__init__里初始化self.stop = False和self.dataframe = prevframe.copy(),确保实例变量存在
  2. 更新逻辑重构:

    • 把原update方法改成update_table,去掉多余的data参数,改成循环获取数据直到self.stop为True
    • 修复了DataFrame行添加的逻辑:直接用列表构造一行数据,避免数组转置的错误
  3. 线程管理:

    • 启动线程时判断线程是否存活,避免重复启动多个线程
    • 设置线程为daemon=True,确保关闭窗口时线程自动退出
  4. 数据持久化:

    • 每次更新表格后,把完整的DataFrame写入CSV,保证历史数据不会丢失
  5. MQTT数据接入:

    • 预留了MQTT数据获取的位置,你只需要把模拟数据的部分替换成实际从MQTT订阅接收的列表数据即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:23:32