电表及销售统计Python应用及win程序2

接着上一篇给代码添加了表格功能,方便更好的处理数据。

import json
import os
from datetime import datetime
from tkinter import *
from tkinter import messagebox
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
import pandas as pd

def update_data(filename, data_name, value):
    """更新数据文件中的数据"""
    with open(filename, 'r') as file:
        data = json.load(file)
    if data_name not in data:
        data[data_name] = []
    current_time = datetime.now().isoformat()
    if data[data_name]:
        prev_value = data[data_name][-1]['value']
        difference = value - prev_value
    else:
        difference = None
    data[data_name].append({"time": current_time, "value": value, "difference": difference})
    with open(filename, 'w') as file:
        json.dump(data, file)

def read_data(filename):
    """从数据文件中读取数据"""
    if os.path.exists(filename):
        with open(filename, 'r') as file:
            return json.load(file)
    return {}

class DataApp:
    def __init__(self, master):
        self.master = master
        self.master.title("数据记录器")
        self.filename = 'data_records.json'
        self.init_data_file()  # 调用初始化数据文件的方法
        # 创建输入框和按钮
        Label(master, text="数据名称:").grid(row=0)
        self.data_name_entry = Entry(master)
        self.data_name_entry.grid(row=0, column=1)

        Label(master, text="数据值:").grid(row=1)
        self.data_value_entry = Entry(master)
        self.data_value_entry.grid(row=1, column=1)

        self.update_button = Button(master, text="更新数据", command=self.update_data_gui)
        self.update_button.grid(row=2, column=1)

        self.analyze_button = Button(master, text="分析数据", command=self.analyze_data)
        self.analyze_button.grid(row=3, column=1)

        self.clear_button = Button(master, text="清空数据库", command=self.clear_data)
        self.clear_button.grid(row=4, column=1)

        self.quit_button = Button(master, text="退出", command=master.quit)
        self.quit_button.grid(row=5, column=1)

        # 图表区域
        self.figure = Figure(figsize=(6, 4), dpi=100)
        self.ax = self.figure.add_subplot(111)
        self.canvas = FigureCanvasTkAgg(self.figure, master=master)
        self.canvas.get_tk_widget().grid(row=0, column=2, rowspan=6)

        # 初始化数据文件(如果文件不存在,则创建空字典)

    def init_data_file(self):
        if not os.path.exists(self.filename):
            with open(self.filename, 'w') as file:
                json.dump({}, file)

                # 数据清空功能

    def clear_data(self):
        confirm = messagebox.askyesno("警告", "您确定要清空所有数据吗?此操作不可逆!")
        if confirm:
            with open(self.filename, 'w') as file:
                json.dump({}, file)
            messagebox.showinfo("成功", "数据已清空。")
            self.analyze_data()  # 可选:清空后重新分析数据
        else:
            messagebox.showinfo("取消", "数据清空操作已取消。")
    # GUI版本的更新数据函数
    def update_data_gui(self):
        data_name = self.data_name_entry.get()
        try:
            new_value = float(self.data_value_entry.get())
            update_data(self.filename, data_name, new_value)
            messagebox.showinfo("成功", f"数据 {data_name} 已更新,并记录了差值和时间。")
        except ValueError:
            messagebox.showerror("错误", "请输入有效的数字!")

    # 数据分析图表函数
    def analyze_data(self):
        data_name = self.data_name_entry.get()
        data = read_data(self.filename)

        if data_name in data:
            times = [record["time"] for record in data[data_name]]
            values = [record["value"] for record in data[data_name]]
            differences = [record["difference"] for record in data[data_name]]

            self.ax.clear()
            self.ax.plot(times, values, label='Values', marker='o')
            self.ax.plot(times, differences, label='Differences', marker='x')

            # 在每个点旁边添加数值标签
            for i, (val, diff) in enumerate(zip(values, differences)):
                self.ax.text(times[i], val, f'{val:.2f}', ha='center', va='bottom')
                self.ax.text(times[i], diff, f'{diff:.2f}', ha='center', va='top')

            self.ax.legend()
            self.ax.set_title(f"{data_name} Analysis")
            self.canvas.draw()

            # 添加Excel导出按钮
            self.export_button = Button(self.master, text="导出至Excel", command=lambda: self.export_to_excel(data_name))
            self.export_button.grid(row=6, column=1)
        else:
            messagebox.showerror("错误", f"数据名称 {data_name} 未找到!")

    # Excel导出功能
    def export_to_excel(self, data_name):
        data = read_data(self.filename)

        if data_name in data:
            records = data[data_name]
            df = pd.DataFrame(records)
            df['Time'] = pd.to_datetime(df['time'], format='ISO8601')  # 明确指定格式
            df.rename(columns={'time': 'Time'}, inplace=True)

            # 使用ExcelWriter,并设置if_sheet_exists为'replace'来覆盖已存在的工作表
            with pd.ExcelWriter('data_records.xlsx', engine='openpyxl', mode='a', if_sheet_exists='replace') as writer:
                df.to_excel(writer, sheet_name=data_name, index=False)

            messagebox.showinfo("成功", f"数据 {data_name} 已导出到Excel文件。")
        else:
            messagebox.showerror("错误", f"数据名称 {data_name} 未找到!无法导出。")


# 主程序入口
if __name__ == "__main__":
    root = Tk()
    app = DataApp(root)
    root.mainloop()

效果如下

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值