|
|
# -*- coding: utf-8 -*-
|
|
|
import tkinter as tk
|
|
|
from tkinter import ttk
|
|
|
from tkinter import Toplevel
|
|
|
import random
|
|
|
import time
|
|
|
import matplotlib.pyplot as plt
|
|
|
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
|
|
|
|
|
|
class EnvironmentMonitorApp:
|
|
|
def __init__(self, root):
|
|
|
self.root = root
|
|
|
self.root.title("环境监测数据展示")
|
|
|
self.setup_ui()
|
|
|
self.data_records = [] # 保存所有监测记录
|
|
|
self.plot_window = None # 初始化图表窗口变量
|
|
|
self.figure = None # 初始化图表figure变量
|
|
|
self.canvas = None # 初始化图表canvas变量
|
|
|
self.axs = None # 初始化子图变量
|
|
|
self.root.after(5000, self.update_data_and_display) # 每5秒更新一次数据
|
|
|
|
|
|
# 设置matplotlib的字体以支持中文显示
|
|
|
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
|
|
|
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
|
|
|
def setup_ui(self):
|
|
|
# 调整窗口大小以适应更多数据
|
|
|
self.root.geometry("800x600") # 或根据实际需要调整
|
|
|
|
|
|
self.treeview = ttk.Treeview(self.root, columns=("序号", "温度", "湿度", "光照强度"), show="headings")
|
|
|
self.treeview.column("序号", width=50, anchor=tk.CENTER)
|
|
|
self.treeview.column("温度", width=100, anchor=tk.CENTER)
|
|
|
self.treeview.column("湿度", width=100, anchor=tk.CENTER)
|
|
|
self.treeview.column("光照强度", width=120, anchor=tk.CENTER)
|
|
|
self.treeview.heading("序号", text="序号")
|
|
|
self.treeview.heading("温度", text="温度")
|
|
|
self.treeview.heading("湿度", text="湿度")
|
|
|
self.treeview.heading("光照强度", text="光照强度")
|
|
|
self.treeview.pack(expand=True, fill=tk.BOTH, padx=10, pady=10) # 让Treeview自适应填充空间
|
|
|
self.plot_button = ttk.Button(self.root, text="查看走势图", command=self.show_plot_window)
|
|
|
self.plot_button.pack(pady=10) # 也可以根据需要调整按钮的位置
|
|
|
|
|
|
|
|
|
def simulate_data(self):
|
|
|
self.temperature = random.uniform(-15, 45)#18-25
|
|
|
self.humidity = random.uniform(0, 100)#30-60
|
|
|
self.light_intensity = random.randint(100, 1000)#300-500
|
|
|
self.data_records.append({
|
|
|
"序号": len(self.data_records) + 1,
|
|
|
"温度": self.temperature,
|
|
|
"湿度": self.humidity,
|
|
|
"光照强度": self.light_intensity
|
|
|
})
|
|
|
self.update_treeview()
|
|
|
if self.plot_window and self.figure and self.canvas:
|
|
|
self.update_plots()
|
|
|
|
|
|
def update_treeview(self):
|
|
|
# 更新表格数据,每行包含一条完整记录
|
|
|
self.treeview.delete(*self.treeview.get_children())
|
|
|
for record in self.data_records:
|
|
|
self.treeview.insert("", tk.END, values=(
|
|
|
record["序号"],
|
|
|
f"{record['温度']:.2f} °C",
|
|
|
f"{record['湿度']:.2f}%",
|
|
|
f"{record['光照强度']} lux"
|
|
|
))
|
|
|
|
|
|
def update_data_and_display(self):
|
|
|
self.simulate_data()
|
|
|
self.root.after(5000, self.update_data_and_display)
|
|
|
|
|
|
def on_plot_window_close(self):
|
|
|
self.plot_window.destroy()
|
|
|
self.plot_window = None # 关闭窗口后重置plot_window为None,以便下次能重新创建
|
|
|
|
|
|
def show_plot_window(self):
|
|
|
if not self.plot_window:
|
|
|
self.plot_window = Toplevel(self.root)
|
|
|
self.plot_window.protocol("WM_DELETE_WINDOW", self.on_plot_window_close) # 添加关闭窗口的回调
|
|
|
self.plot_window.title("环境数据走势图")
|
|
|
self.figure, self.axs = plt.subplots(3, 1, figsize=(6, 8), sharex=True)
|
|
|
self.figure.suptitle('环境数据实时走势图')
|
|
|
self.axs[0].set_title('温度变化')
|
|
|
self.axs[1].set_title('湿度变化')
|
|
|
self.axs[2].set_title('光照强度变化')
|
|
|
for ax in self.axs:
|
|
|
ax.legend()
|
|
|
ax.grid(True)
|
|
|
|
|
|
self.canvas = FigureCanvasTkAgg(self.figure, master=self.plot_window)
|
|
|
self.canvas.draw()
|
|
|
self.canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)
|
|
|
|
|
|
def update_plots(self):
|
|
|
for ax, key in zip(self.axs, ["温度", "湿度", "光照强度"]):
|
|
|
ax.clear() # 清除旧的图表
|
|
|
ax.set_title(f'{key}变化') # 设置子图标题
|
|
|
ax.plot([r['序号'] for r in self.data_records], [r[key] for r in self.data_records], label=key)
|
|
|
ax.legend()
|
|
|
ax.grid(True)
|
|
|
self.canvas.draw_idle() # 更新图表而不重新绘制整个画布
|
|
|
|
|
|
|
|
|
def main():
|
|
|
root = tk.Tk()
|
|
|
app = EnvironmentMonitorApp(root)
|
|
|
root.mainloop()
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
main() |