|
|
|
|
import tkinter as tk
|
|
|
|
|
from tkinter import ttk
|
|
|
|
|
from tkinter import Toplevel
|
|
|
|
|
import random
|
|
|
|
|
import matplotlib.pyplot as plt
|
|
|
|
|
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
|
|
|
|
|
|
|
|
|
|
# 初始化全局变量
|
|
|
|
|
root = tk.Tk()
|
|
|
|
|
root.title("智能家居系统-环境监测数据展示")
|
|
|
|
|
|
|
|
|
|
# 数据结构和全局变量
|
|
|
|
|
data_records = []
|
|
|
|
|
plot_window = None
|
|
|
|
|
figure = None
|
|
|
|
|
canvas = None
|
|
|
|
|
axs = None
|
|
|
|
|
|
|
|
|
|
# 函数定义
|
|
|
|
|
|
|
|
|
|
def setup_ui():
|
|
|
|
|
"""UI设置"""
|
|
|
|
|
root.geometry("800x600")
|
|
|
|
|
|
|
|
|
|
def simulate_data():
|
|
|
|
|
"""数据模拟"""
|
|
|
|
|
global temperature, humidity, light_intensity, pm2_5
|
|
|
|
|
temperature = random.uniform(-15, 45)
|
|
|
|
|
humidity = random.uniform(0, 100)
|
|
|
|
|
light_intensity = random.randint(100, 1000)
|
|
|
|
|
pm2_5 = random.uniform(0, 300) # 假定PM2.5浓度范围
|
|
|
|
|
data_records.append({
|
|
|
|
|
"序号": len(data_records) + 1,
|
|
|
|
|
"温度": temperature,
|
|
|
|
|
"湿度": humidity,
|
|
|
|
|
"光照强度": light_intensity,
|
|
|
|
|
"PM2.5": pm2_5
|
|
|
|
|
})
|
|
|
|
|
update_treeview()
|
|
|
|
|
if plot_window and figure and canvas:
|
|
|
|
|
update_plots()
|
|
|
|
|
|
|
|
|
|
def update_treeview():
|
|
|
|
|
"""更新表格视图,包含PM2.5列及其等级"""
|
|
|
|
|
treeview.delete(*treeview.get_children())
|
|
|
|
|
for record in data_records:
|
|
|
|
|
pm2_5_level_tag = get_pm2_5_level(record["PM2.5"])
|
|
|
|
|
treeview.insert("", tk.END, values=(
|
|
|
|
|
record["序号"],
|
|
|
|
|
f"{record['温度']:.2f} °C",
|
|
|
|
|
f"{record['湿度']:.2f}%",
|
|
|
|
|
f"{record['光照强度']} lux",
|
|
|
|
|
f"{record['PM2.5']:.2f} µg/m³{pm2_5_level_tag}"
|
|
|
|
|
))
|
|
|
|
|
|
|
|
|
|
def update_data_and_display():
|
|
|
|
|
"""定时更新数据"""
|
|
|
|
|
simulate_data()
|
|
|
|
|
root.after(5000, update_data_and_display)
|
|
|
|
|
|
|
|
|
|
def on_plot_window_close():
|
|
|
|
|
"""图表窗口关闭事件处理"""
|
|
|
|
|
global plot_window
|
|
|
|
|
plot_window.destroy()
|
|
|
|
|
plot_window = None
|
|
|
|
|
|
|
|
|
|
def show_plot_window():
|
|
|
|
|
"""显示图表窗口,更新图表以包含PM2.5"""
|
|
|
|
|
global plot_window, figure, axs, canvas
|
|
|
|
|
if not plot_window:
|
|
|
|
|
plot_window = Toplevel(root)
|
|
|
|
|
plot_window.protocol("WM_DELETE_WINDOW", on_plot_window_close)
|
|
|
|
|
plot_window.title("智能家居系统-环境数据走势图")
|
|
|
|
|
figure, axs = plt.subplots(4, 1, figsize=(6, 10), sharex=True)
|
|
|
|
|
figure.suptitle('智能家居系统-环境数据走势图')
|
|
|
|
|
keys = ["温度", "湿度", "光照强度", "PM2.5"]
|
|
|
|
|
for i, key in enumerate(keys):
|
|
|
|
|
axs[i].set_title(f'{key}变化')
|
|
|
|
|
axs[i].plot([r['序号'] for r in data_records], [r[key] for r in data_records], label=key)
|
|
|
|
|
axs[i].legend()
|
|
|
|
|
axs[i].grid(True)
|
|
|
|
|
canvas = FigureCanvasTkAgg(figure, master=plot_window)
|
|
|
|
|
canvas.draw()
|
|
|
|
|
canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)
|
|
|
|
|
|
|
|
|
|
def update_plots():
|
|
|
|
|
"""更新图表,包含PM2.5图"""
|
|
|
|
|
for ax, key in zip(axs, ["温度", "湿度", "光照强度", "PM2.5"]):
|
|
|
|
|
ax.clear()
|
|
|
|
|
ax.plot([r['序号'] for r in data_records], [r[key] for r in data_records], label=key)
|
|
|
|
|
ax.set_title(f'{key}变化')
|
|
|
|
|
ax.legend()
|
|
|
|
|
ax.grid(True)
|
|
|
|
|
canvas.draw_idle()
|
|
|
|
|
|
|
|
|
|
# 设置matplotlib字体
|
|
|
|
|
plt.rcParams['font.sans-serif'] = ['SimHei']
|
|
|
|
|
plt.rcParams['axes.unicode_minus'] = False
|
|
|
|
|
|
|
|
|
|
# UI组件初始化,添加PM2.5列
|
|
|
|
|
treeview = ttk.Treeview(root, columns=("序号", "温度", "湿度", "光照强度", "PM2.5"), show="headings")
|
|
|
|
|
treeview.column("序号", width=50, anchor=tk.CENTER)
|
|
|
|
|
treeview.column("温度", width=100, anchor=tk.CENTER)
|
|
|
|
|
treeview.column("湿度", width=100, anchor=tk.CENTER)
|
|
|
|
|
treeview.column("光照强度", width=120, anchor=tk.CENTER)
|
|
|
|
|
treeview.column("PM2.5", width=100, anchor=tk.CENTER)
|
|
|
|
|
treeview.heading("序号", text="序号")
|
|
|
|
|
treeview.heading("温度", text="温度")
|
|
|
|
|
treeview.heading("湿度", text="湿度")
|
|
|
|
|
treeview.heading("光照强度", text="光照强度")
|
|
|
|
|
treeview.heading("PM2.5", text="PM2.5")
|
|
|
|
|
treeview.pack(expand=True, fill=tk.BOTH, padx=10, pady=10)
|
|
|
|
|
|
|
|
|
|
plot_button = ttk.Button(root, text="查看走势图", command=show_plot_window)
|
|
|
|
|
plot_button.pack(pady=10)
|
|
|
|
|
|
|
|
|
|
setup_ui()
|
|
|
|
|
|
|
|
|
|
def get_pm2_5_level(pm2_5_value):
|
|
|
|
|
"""根据PM2.5值返回其等级标签"""
|
|
|
|
|
if 0 <= pm2_5_value <= 35:
|
|
|
|
|
return "(优)"
|
|
|
|
|
elif 35 < pm2_5_value <= 75:
|
|
|
|
|
return "(良)"
|
|
|
|
|
elif 75 < pm2_5_value <= 115:
|
|
|
|
|
return "(轻度污染)"
|
|
|
|
|
elif 115 < pm2_5_value <= 150:
|
|
|
|
|
return "(中度污染)"
|
|
|
|
|
elif 150 < pm2_5_value <= 250:
|
|
|
|
|
return "(重度污染)"
|
|
|
|
|
else:
|
|
|
|
|
return "(严重污染)"
|
|
|
|
|
|
|
|
|
|
# 主循环启动
|
|
|
|
|
update_data_and_display()
|
|
|
|
|
root.mainloop()
|