From a8838866e5dd5b6a60bcd6edc794200f14d322d6 Mon Sep 17 00:00:00 2001 From: 123 <2070873540@qq.com> Date: Tue, 4 Jun 2024 22:46:17 +0800 Subject: [PATCH] 9 commit --- 智能家居系统/5.1.py | 136 ++++++++++ 智能家居系统/6.1.py | 69 +++++ 智能家居系统/6.py | 141 +++------- 智能家居系统/DL.py | 41 +++ 智能家居系统/HJJC.py | 137 ++++++++++ 智能家居系统/JJXX.py | 256 ++++++++++++++++++ 智能家居系统/KTTJ.py | 69 +++++ 智能家居系统/ZYM.py | 30 ++ .../__pycache__/JJXX.cpython-311.pyc | Bin 0 -> 19505 bytes .../__pycache__/ZYM.cpython-311.pyc | Bin 0 -> 1660 bytes .../__pycache__/主页面.cpython-311.pyc | Bin 2872 -> 2872 bytes .../__pycache__/家居信息.cpython-311.pyc | Bin 20085 -> 20085 bytes .../__pycache__/空调调节.cpython-311.pyc | Bin 0 -> 5235 bytes 智能家居系统/temp_data.txt | 1 + 智能家居系统/登录界面.py | 2 +- 智能家居系统/空调调节.py | 153 +++-------- 计科2101 雷浩 21412030125.doc | Bin 723456 -> 751104 bytes 17 files changed, 814 insertions(+), 221 deletions(-) create mode 100644 智能家居系统/5.1.py create mode 100644 智能家居系统/6.1.py create mode 100644 智能家居系统/DL.py create mode 100644 智能家居系统/HJJC.py create mode 100644 智能家居系统/JJXX.py create mode 100644 智能家居系统/KTTJ.py create mode 100644 智能家居系统/ZYM.py create mode 100644 智能家居系统/__pycache__/JJXX.cpython-311.pyc create mode 100644 智能家居系统/__pycache__/ZYM.cpython-311.pyc create mode 100644 智能家居系统/__pycache__/空调调节.cpython-311.pyc create mode 100644 智能家居系统/temp_data.txt diff --git a/智能家居系统/5.1.py b/智能家居系统/5.1.py new file mode 100644 index 0000000..2762efb --- /dev/null +++ b/智能家居系统/5.1.py @@ -0,0 +1,136 @@ +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() \ No newline at end of file diff --git a/智能家居系统/6.1.py b/智能家居系统/6.1.py new file mode 100644 index 0000000..d61a341 --- /dev/null +++ b/智能家居系统/6.1.py @@ -0,0 +1,69 @@ +import tkinter as tk +from tkinter import ttk +import random +import time + +# 全局变量 +comfortable_temperature_range = (20, 24) +comfortable_humidity_range = (40, 60) +current_temperature = 0 +current_humidity = 0 +line_number = 0 +update_interval = 5000 # 每5秒更新一次 +root = None +treeview = None + +def reset_conditions(): + global current_temperature, current_humidity + current_temperature = random.uniform(-12, 42) + current_humidity = random.uniform(0, 100) + +def adjust(): + global current_temperature, current_humidity + reset_conditions() + if not comfortable_temperature_range[0] <= current_temperature <= comfortable_temperature_range[1]: + current_temperature = random.uniform(*comfortable_temperature_range) + if not comfortable_humidity_range[0] <= current_humidity <= comfortable_humidity_range[1]: + current_humidity = random.uniform(*comfortable_humidity_range) + return current_temperature, current_humidity + +def schedule_update(): + """计划下一次更新""" + global line_number + line_number += 1 + initial_temp, initial_humidity = current_temperature, current_humidity + adjusted_temp, adjusted_humidity = adjust() + treeview.insert("", tk.END, values=(line_number, + f"{initial_temp:.2f}°C", + f"{initial_humidity:.2f}%", + f"{adjusted_temp:.2f}°C", + f"{adjusted_humidity:.2f}%")) + # 安排下一次更新 + root.after(update_interval, schedule_update) + +def main(): + global root, treeview + root = tk.Tk() + root.title("智能家居系统-空调自动调节系统") + root.geometry("800x600") + + treeview = ttk.Treeview(root, + columns=("编号", "初始温度", "初始湿度", "调节后温度", "调节后湿度"), + show="headings") + treeview.heading("编号", text="编号") + treeview.heading("初始温度", text="初始温度") + treeview.heading("初始湿度", text="初始湿度") + treeview.heading("调节后温度", text="调节后温度") + treeview.heading("调节后湿度", text="调节后湿度") + for col in treeview['columns']: + treeview.column(col, width=80, anchor=tk.CENTER) + treeview.pack(fill=tk.BOTH, expand=True, padx=10, pady=10) + + root.rowconfigure(0, weight=1) + root.columnconfigure(0, weight=1) + + schedule_update() # 安排首次更新 + root.mainloop() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/智能家居系统/6.py b/智能家居系统/6.py index ff3ff6a..7f6b1fb 100644 --- a/智能家居系统/6.py +++ b/智能家居系统/6.py @@ -5,129 +5,62 @@ import time class AirConditioner: def __init__(self): - self.current_temperature = random.uniform(16, 30) - self.current_humidity = random.uniform(0, 100) - self.min_temperature = 16 - self.max_temperature = 30 - self.min_humidity = 0 - self.max_humidity = 100 - self.comfortable_temperature_range = (20, 24) # 舒适温度范围 - self.comfortable_humidity_range = (40, 60) # 舒适湿度范围 - - def adjust_temperature(self): - if not self.comfortable_temperature_range[0] <= self.current_temperature <= self.comfortable_temperature_range[ - 1]: - if self.current_temperature < self.comfortable_temperature_range[0]: - - self.current_temperature += 1 - elif self.current_temperature > self.comfortable_temperature_range[1]: - - self.current_temperature -= 1 - - def adjust_humidity(self): - if not self.comfortable_humidity_range[0] <= self.current_humidity <= self.comfortable_humidity_range[1]: - if self.current_humidity < self.comfortable_humidity_range[0]: - - self.current_humidity += 5 - elif self.current_humidity > self.comfortable_humidity_range[1]: - - self.current_humidity -= 5 + self.comfortable_temperature_range = (20, 24) # 添加舒适温度范围 + self.comfortable_humidity_range = (40, 60) # 添加舒适湿度范围 + self.reset_conditions() - def display_status(self): - print(f"当前温度: {self.current_temperature:.1f}°C, 当前湿度: {self.current_humidity:.1f}%") + def reset_conditions(self): + self.current_temperature = random.uniform(-12, 42) + self.current_humidity = random.uniform(0, 100) - def main_loop(self, root): # 接受root参数 + def adjust(self): + self.reset_conditions() # 获取新的初始温度和湿度 if not self.comfortable_temperature_range[0] <= self.current_temperature <= self.comfortable_temperature_range[1]: - self.adjust_temperature() + self.current_temperature = random.uniform(*self.comfortable_temperature_range) if not self.comfortable_humidity_range[0] <= self.current_humidity <= self.comfortable_humidity_range[1]: - self.adjust_humidity() - - if not ( - self.comfortable_temperature_range[0] <= self.current_temperature <= self.comfortable_temperature_range[1] - and - self.comfortable_humidity_range[0] <= self.current_humidity <= self.comfortable_humidity_range[1] - ): - self.display_status() - root.after(1000, self.main_loop, root) # 使用after而非sleep - else: - print("温度和湿度均在舒适范围内,停止调节。") - print(f"温度: {self.current_temperature:.1f}°C, 湿度: {self.current_humidity:.1f}%") - # 可能需要在这里调用一次update_gui以最终更新GUI显示结果 - # self.app.update_gui_final() 如果在ACApp类中实现了这个方法来显示最终状态 - + self.current_humidity = random.uniform(*self.comfortable_humidity_range) + return self.current_temperature, self.current_humidity # 返回调节后的温度和湿度 class ACApp(tk.Tk): def __init__(self): super().__init__() self.title("空调自动调节系统") - self.geometry("800x600") # 调整窗口大小以适应内容 + self.geometry("800x600") - # 创建Treeview表格 - self.treeview = ttk.Treeview(self, columns=("编号", "初始温度", "初始湿度", "调节后温度", "调节后湿度"), + self.treeview = ttk.Treeview(self, + columns=("编号", "初始温度", "初始湿度", "调节后温度", "调节后湿度"), show="headings") self.treeview.heading("编号", text="编号") self.treeview.heading("初始温度", text="初始温度") self.treeview.heading("初始湿度", text="初始湿度") self.treeview.heading("调节后温度", text="调节后温度") self.treeview.heading("调节后湿度", text="调节后湿度") - self.treeview.column("编号", width=50, anchor=tk.CENTER) - self.treeview.column("初始温度", width=80, anchor=tk.CENTER) - self.treeview.column("初始湿度", width=80, anchor=tk.CENTER) - self.treeview.column("调节后温度", width=80, anchor=tk.CENTER) - self.treeview.column("调节后湿度", width=80, anchor=tk.CENTER) + for col in self.treeview['columns']: + self.treeview.column(col, width=80, anchor=tk.CENTER) self.treeview.grid(row=0, column=0, columnspan=4, padx=10, pady=10) self.aircon = AirConditioner() - self.line_number = 1 # 初始化行编号 - self.is_adjusting = True # 添加标志位,判断是否仍在调节过程中 - self.update_gui() # 先更新一次GUI - self.aircon.main_loop(self) # 传递self给main_loop以便使用after方法 - - self.treeview.pack(expand=True, fill=tk.BOTH, padx=10, pady=10) # 让Treeview自适应填充空间 - self.rowconfigure(0, weight=1) # 让树状视图所在的行填充额外空间 - self.columnconfigure(0, weight=1) # 让树状视图所在的列填充额外空间 - def update_gui(self): - if self.is_adjusting: # 只在调节过程中更新数据 - # 更新Treeview中的数据,这里假设初始数据就是当前数据,实际应用中可能需要记录调节前的实际初始值 - self.treeview.insert("", tk.END, values=(self.line_number, - f"{self.aircon.current_temperature:.1f}°C", - f"{self.aircon.current_humidity:.1f}%", - f"{self.aircon.current_temperature:.1f}°C", - f"{self.aircon.current_humidity:.1f}%")) - self.line_number += 1 - else: # 调节完成后,添加最终状态 - if self.line_number == 1: # 如果还没有插入过数据,则插入第一行 - self.treeview.insert("", tk.END, values=(self.line_number, - f"{self.aircon.current_temperature:.1f}°C", - f"{self.aircon.current_humidity:.1f}%", - f"{self.aircon.current_temperature:.1f}°C", - f"{self.aircon.current_humidity:.1f}%")) - self.line_number += 1 - print("温度和湿度均在舒适范围内,停止调节。") - print(f"温度: {self.current_temperature:.1f}°C, 湿度: {self.current_humidity:.1f}%") - self.is_adjusting = False # 设置标志位为False,停止调节后的数据更新 - - def main_loop(self, root): - if self.is_adjusting: - if not self.comfortable_temperature_range[0] <= self.current_temperature <= \ - self.comfortable_temperature_range[1]: - self.adjust_temperature() - if not self.comfortable_humidity_range[0] <= self.current_humidity <= self.comfortable_humidity_range[1]: - self.adjust_humidity() - - if not ( - self.comfortable_temperature_range[0] <= self.current_temperature <= - self.comfortable_temperature_range[1] - and - self.comfortable_humidity_range[0] <= self.current_humidity <= self.comfortable_humidity_range[1] - ): - self.display_status() - root.after(1000, self.main_loop, root) - else: - self.is_adjusting = False # 温湿度达到舒适范围后,设置标志位为False - else: - self.update_gui() # 最后调用一次update_gui以显示最终状态 - + self.line_number = 0 + self.is_adjusted = False + self.update_interval = 5000 # 每5秒更新一次 + self.schedule_update() # 安排首次更新 + + self.treeview.pack(fill=tk.BOTH, expand=True, padx=10, pady=10) + self.rowconfigure(0, weight=1) + self.columnconfigure(0, weight=1) + + def schedule_update(self): + """计划下一次更新""" + self.line_number += 1 + initial_temp, initial_humidity = self.aircon.current_temperature, self.aircon.current_humidity + adjusted_temp, adjusted_humidity = self.aircon.adjust() + self.treeview.insert("", tk.END, values=(self.line_number, + f"{initial_temp:.1f}°C", + f"{initial_humidity:.1f}%", + f"{adjusted_temp:.1f}°C", + f"{adjusted_humidity:.1f}%")) + # 安排下一次更新 + self.after(self.update_interval, self.schedule_update) if __name__ == "__main__": app = ACApp() diff --git a/智能家居系统/DL.py b/智能家居系统/DL.py new file mode 100644 index 0000000..9fc9c5d --- /dev/null +++ b/智能家居系统/DL.py @@ -0,0 +1,41 @@ +import tkinter as tk +from tkinter import messagebox +from ZYM import a + +def login_check(root, username_var, password_var): + name = username_var.get() + pwd = password_var.get() + + if name == '123' and pwd == '123': + messagebox.showinfo(title='恭喜', message='登录成功') + xiaohui() + # MainPage(root) # 如果需要,取消注释此行并确保已正确导入主页面模块 + else: + messagebox.showinfo(title='错误', message='账户或密码错误') + +def main(): + global root + root = tk.Tk() + root.title('智能家居系统-登录界面') + root.geometry("300x180") + + username_var = tk.StringVar() + password_var = tk.StringVar() + + tk.Label(root).grid(row=0, column=0) + tk.Label(root, text='账户').grid(row=1,column=0) + tk.Entry(root, textvariable=username_var).grid(row=1, column=1) + tk.Label(root, text='密码').grid(row=2, column=0) + tk.Entry(root, textvariable=password_var).grid(row=2, column=1, pady=10) + + tk.Button(root, text='登录', command=lambda: login_check(root, username_var, password_var)).grid(row=3, column=0, pady=10) + tk.Button(root, text='退出', command=root.quit).grid(row=3, column=1, pady=10, sticky=tk.E) + + root.mainloop() + +def xiaohui(): + root.destroy() + a() + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/智能家居系统/HJJC.py b/智能家居系统/HJJC.py new file mode 100644 index 0000000..cf7a87c --- /dev/null +++ b/智能家居系统/HJJC.py @@ -0,0 +1,137 @@ +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, 5000) + 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() \ No newline at end of file diff --git a/智能家居系统/JJXX.py b/智能家居系统/JJXX.py new file mode 100644 index 0000000..c509d34 --- /dev/null +++ b/智能家居系统/JJXX.py @@ -0,0 +1,256 @@ +import tkinter as tk +from tkinter import ttk +import pymysql +from tkinter import messagebox + + + + +# 初始化数据库连接 +def init_db_connection(): + global conn, cursor + conn = pymysql.connect(host='localhost', user='root', password='LH20021212', db='智能家居系统', charset='utf8mb4') + cursor = conn.cursor() + + +# 创建主界面 +def create_main_window(): + global root, tree, entry_name_query, entry_color_query, entry_brand_query, entry_price_query, entry_production_date_query, button_frame, query_frame + + root = tk.Tk() + root.title("智能家居系统-家居信息") + root.geometry('1000x700') + + init_db_connection() + create_widgets() + + root.protocol("WM_DELETE_WINDOW", close_conn) + root.mainloop() + + +# 创建界面组件 +def create_widgets(): + global tree, entry_name_query, entry_color_query, entry_brand_query, entry_price_query, entry_production_date_query, button_frame, query_frame + + # 表格和滚动条 + frame = tk.Frame(root) + frame.pack(fill=tk.BOTH, expand=True) + scrollbar_y = tk.Scrollbar(frame, orient=tk.VERTICAL) + scrollbar_x = tk.Scrollbar(frame, orient=tk.HORIZONTAL) + + tree = ttk.Treeview(frame, columns=("ID", "名称", "颜色", "品牌", "价格", "生产日期"), + yscrollcommand=scrollbar_y.set, xscrollcommand=scrollbar_x.set) + tree.heading("#0", text="") + tree.heading("ID", text="ID") + tree.heading("名称", text="名称") + tree.heading("颜色", text="颜色") + tree.heading("品牌", text="品牌") + tree.heading("价格", text="价格") + tree.heading("生产日期", text="生产日期") + tree.column("#0", width=0, stretch=tk.NO) + tree.column("ID", anchor=tk.CENTER, width=50) + tree.column("名称", anchor=tk.CENTER, width=100) + tree.column("颜色", anchor=tk.CENTER, width=100) + tree.column("品牌", anchor=tk.CENTER, width=100) + tree.column("价格", anchor=tk.CENTER, width=100) + tree.column("生产日期", anchor=tk.CENTER, width=100) + + tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) + scrollbar_y.config(command=tree.yview) + scrollbar_y.pack(side=tk.RIGHT, fill=tk.Y) + scrollbar_x.config(command=tree.xview) + scrollbar_x.pack(side=tk.BOTTOM, fill=tk.X) + + # 按钮区域 + button_frame = tk.Frame(root) + button_frame.pack(pady=10) + tk.Button(button_frame, text="添加家居", command=add_jiaju_popup).pack(side=tk.LEFT, padx=10) + tk.Button(button_frame, text="删除选中", command=delete_selected_jiaju).pack(side=tk.LEFT, padx=10) + tk.Button(button_frame, text="修改选中", command=update_selected_jiaju_popup).pack(side=tk.LEFT, padx=10) + tk.Button(button_frame, text="查询所有", command=query_all_jiaju).pack(side=tk.LEFT, padx=10) + tk.Button(button_frame, text="返回", command=root.destroy).pack(side=tk.LEFT, padx=10) + + # 查询条件输入框区域 + query_frame = tk.Frame(root) + query_frame.pack(pady=(10, 0)) + tk.Label(query_frame, text="名称:").pack(side=tk.LEFT) + entry_name_query = tk.Entry(query_frame) + entry_name_query.pack(side=tk.LEFT, padx=(5, 0)) + tk.Label(query_frame, text="颜色:").pack(side=tk.LEFT) + entry_color_query = tk.Entry(query_frame) + entry_color_query.pack(side=tk.LEFT, padx=(5, 0)) + tk.Label(query_frame, text="品牌:").pack(side=tk.LEFT) + entry_brand_query = tk.Entry(query_frame) + entry_brand_query.pack(side=tk.LEFT, padx=(5, 0)) + tk.Label(query_frame, text="价格:").pack(side=tk.LEFT) + entry_price_query = tk.Entry(query_frame) + entry_price_query.pack(side=tk.LEFT, padx=(5, 0)) + tk.Label(query_frame, text="生产日期:").pack(side=tk.LEFT) + entry_production_date_query = tk.Entry(query_frame) + entry_production_date_query.pack(side=tk.LEFT) + tk.Button(query_frame, text="查询", command=query_jiaju_condition).pack(side=tk.LEFT, padx=10) + + query_all_jiaju() + + +# 查询所有家居信息 +def query_all_jiaju(): + tree.delete(*tree.get_children()) + cursor.execute("SELECT * FROM jia_ju") + rows = cursor.fetchall() + for row in rows: + tree.insert('', tk.END, values=row) + + +# 添加家居弹窗 +def add_jiaju_popup(): + def submit_add(): + name = entry_name.get() + color = entry_color.get() + brand = entry_brand.get() + price = entry_price.get() + production_date = entry_production_date.get() + sql = f"INSERT INTO jia_ju(name, color, brand, price, production_date) VALUES ('{name}', '{color}', '{brand}', {price}, '{production_date}')" + try: + cursor.execute(sql) + conn.commit() + messagebox.showinfo("成功", "家居信息录入成功!") + add_window.destroy() + query_all_jiaju() + except Exception as e: + messagebox.showerror("错误", f"录入失败: {e}") + + add_window = tk.Toplevel(root) + add_window.title("录入家居信息") + tk.Label(add_window, text="名称:").pack() + entry_name = tk.Entry(add_window) + entry_name.pack() + tk.Label(add_window, text="颜色:").pack() + entry_color = tk.Entry(add_window) + entry_color.pack() + tk.Label(add_window, text="品牌:").pack() + entry_brand = tk.Entry(add_window) + entry_brand.pack() + tk.Label(add_window, text="价格:").pack() + entry_price = tk.Entry(add_window) + entry_price.pack() + tk.Label(add_window, text="生产日期:").pack() + entry_production_date = tk.Entry(add_window) + entry_production_date.pack() + tk.Button(add_window, text="提交", command=submit_add).pack() + +# 删除选中家居 +def delete_selected_jiaju(self): + selected_items = self.tree.selection() + if not selected_items: + messagebox.showwarning("警告", "请先选择要删除的家居项!") + return + for item in selected_items: + item_id = self.tree.item(item)['values'][0] + sql = f"DELETE FROM jia_ju WHERE id={item_id}" + try: + self.cursor.execute(sql) + self.conn.commit() + except Exception as e: + messagebox.showerror("错误", f"删除失败: {e}") + self.conn.rollback() + return + messagebox.showinfo("成功", "选中的家居信息已删除!") + self.query_all_jiaju() # 刷新列表 + +# 修改选中家居弹窗 +def update_selected_jiaju_popup(): + selected_items = tree.selection() + if not selected_items: + messagebox.showwarning("警告", "请先选择要修改的家居项!") + return + + item = selected_items[0] + item_values = tree.item(item)['values'] + item_id = item_values[0] + + def submit_update(): + name = entry_name.get() + color = entry_color.get() + brand = entry_brand.get() + price = entry_price.get() + production_date = entry_production_date.get() + sql = f"UPDATE jia_ju SET name='{name}', color='{color}', brand='{brand}', price={price}, production_date='{production_date}' WHERE id={item_id}" + try: + cursor.execute(sql) + conn.commit() + messagebox.showinfo("成功", "家居信息已更新!") + update_window.destroy() + query_all_jiaju() + except Exception as e: + messagebox.showerror("错误", f"更新失败: {e}") + + update_window = tk.Toplevel(root) + update_window.title("修改家居信息") + tk.Label(update_window, text="名称:").pack() + entry_name = tk.Entry(update_window) + entry_name.insert(tk.END, item_values[1]) + entry_name.pack() + tk.Label(update_window, text="颜色:").pack() + entry_color = tk.Entry(update_window) + entry_color.insert(tk.END, item_values[2]) + entry_color.pack() + tk.Label(update_window, text="品牌:").pack() + entry_brand = tk.Entry(update_window) + entry_brand.insert(tk.END, item_values[3]) + entry_brand.pack() + tk.Label(update_window, text="价格:").pack() + entry_price = tk.Entry(update_window) + entry_price.insert(tk.END, item_values[4]) + entry_price.pack() + tk.Label(update_window, text="生产日期:").pack() + entry_production_date = tk.Entry(update_window) + entry_production_date.insert(tk.END, item_values[5]) + entry_production_date.pack() + tk.Button(update_window, text="提交修改", command=submit_update).pack() + +# 条件查询家居 +def query_jiaju_condition(): + name_cond = entry_name_query.get().strip() + color_cond = entry_color_query.get().strip() + brand_cond = entry_brand_query.get().strip() + price_cond = entry_price_query.get().strip() + production_date_cond = entry_production_date_query.get().strip() + + conditions = [] + if name_cond: + conditions.append(f"name LIKE '%{name_cond}%'") + if color_cond: + conditions.append(f"color LIKE '%{color_cond}%'") + if brand_cond: + conditions.append(f"brand LIKE '%{brand_cond}%'") + if price_cond.isdigit(): + conditions.append(f"price = {price_cond}") + if production_date_cond: + conditions.append(f"production_date = '{production_date_cond}'") + + where_clause = ' AND '.join(conditions) if conditions else '1=1' + sql = f"SELECT * FROM jia_ju WHERE {where_clause}" + + try: + cursor.execute(sql) + rows = cursor.fetchall() + tree.delete(*tree.get_children()) + for row in rows: + tree.insert('', tk.END, values=row) + except Exception as e: + messagebox.showerror("错误", f"查询失败: {e}") + conn.rollback() + +# 关闭数据库连接 +def close_conn(): + cursor.close() + conn.close() + root.destroy() + + + + + +if __name__ == '__main__': + create_main_window() \ No newline at end of file diff --git a/智能家居系统/KTTJ.py b/智能家居系统/KTTJ.py new file mode 100644 index 0000000..d61a341 --- /dev/null +++ b/智能家居系统/KTTJ.py @@ -0,0 +1,69 @@ +import tkinter as tk +from tkinter import ttk +import random +import time + +# 全局变量 +comfortable_temperature_range = (20, 24) +comfortable_humidity_range = (40, 60) +current_temperature = 0 +current_humidity = 0 +line_number = 0 +update_interval = 5000 # 每5秒更新一次 +root = None +treeview = None + +def reset_conditions(): + global current_temperature, current_humidity + current_temperature = random.uniform(-12, 42) + current_humidity = random.uniform(0, 100) + +def adjust(): + global current_temperature, current_humidity + reset_conditions() + if not comfortable_temperature_range[0] <= current_temperature <= comfortable_temperature_range[1]: + current_temperature = random.uniform(*comfortable_temperature_range) + if not comfortable_humidity_range[0] <= current_humidity <= comfortable_humidity_range[1]: + current_humidity = random.uniform(*comfortable_humidity_range) + return current_temperature, current_humidity + +def schedule_update(): + """计划下一次更新""" + global line_number + line_number += 1 + initial_temp, initial_humidity = current_temperature, current_humidity + adjusted_temp, adjusted_humidity = adjust() + treeview.insert("", tk.END, values=(line_number, + f"{initial_temp:.2f}°C", + f"{initial_humidity:.2f}%", + f"{adjusted_temp:.2f}°C", + f"{adjusted_humidity:.2f}%")) + # 安排下一次更新 + root.after(update_interval, schedule_update) + +def main(): + global root, treeview + root = tk.Tk() + root.title("智能家居系统-空调自动调节系统") + root.geometry("800x600") + + treeview = ttk.Treeview(root, + columns=("编号", "初始温度", "初始湿度", "调节后温度", "调节后湿度"), + show="headings") + treeview.heading("编号", text="编号") + treeview.heading("初始温度", text="初始温度") + treeview.heading("初始湿度", text="初始湿度") + treeview.heading("调节后温度", text="调节后温度") + treeview.heading("调节后湿度", text="调节后湿度") + for col in treeview['columns']: + treeview.column(col, width=80, anchor=tk.CENTER) + treeview.pack(fill=tk.BOTH, expand=True, padx=10, pady=10) + + root.rowconfigure(0, weight=1) + root.columnconfigure(0, weight=1) + + schedule_update() # 安排首次更新 + root.mainloop() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/智能家居系统/ZYM.py b/智能家居系统/ZYM.py new file mode 100644 index 0000000..0ae9569 --- /dev/null +++ b/智能家居系统/ZYM.py @@ -0,0 +1,30 @@ +import tkinter as tk +from tkinter import messagebox + +from JJXX import create_main_window + + +def create_main_page(root): + # 创建主页面元素 + home_info_title = tk.Label(root, text="主页面区", font=("Helvetica", 16)) + home_info_title.pack(pady=20) + + # 创建并绑定按钮点击事件,用于显示家居信息 + goto_jiaju_button = tk.Button(root, text="家居信息", command=lambda: JiaJuInfoPage(root)) + goto_jiaju_button.pack(pady=10) + + +def JiaJuInfoPage(master): + # 直接在这里创建家居信息页面,而不是通过类实例化 + # 注意:此处简化处理,未完全实现JiaJuPage逻辑,仅为示例 + create_main_window() + # 根据实际情况调整窗口大小或其他UI元素 + +def a(): + root = tk.Tk() + root.geometry('600x400') + create_main_page(root) + root.mainloop() + +if __name__ == '__main__': + a() \ No newline at end of file diff --git a/智能家居系统/__pycache__/JJXX.cpython-311.pyc b/智能家居系统/__pycache__/JJXX.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ac3ee6a03f77884f287b6ba9a3f155aeab6fdbbe GIT binary patch literal 19505 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 z za6SQ1U)G<`Gc~GicP0SdQF2V27N_`zu#GkJVujus&vYaOfoOO-%4HHanV0IBufh5% zn+PMelLDKo@C3Zap1p1j75e{o4bDuy28TcV%aOPGzvCjeU+ajV4nkhOwX6x+49%If zBG`-ox0B)e*PjN{6O|{k8Ey9dbqB&i03I5tVWH8kLrOm)D;e| z%SJe%CsRhajIai8cJ^Eh=SPfzXY|fdWby!K(!I3F2<_Jc`*pgXAH#6SgB~LpO(>Cw z*%*l=QgRl2S;X{3BB!#^xHZByqGHf2*j50S2%l^j3vLQSfcudd0x;)1CDG*$mWTry zMfW2m;sEM#A1IM}U~xyDF?gL~Z}QzvK)qZQFmhyEfS^I`pphff!k8O3-*gWh97?Ba ztPM{%x3*6J{#vMYUbQy1z%9pFK)F#%BcQ$7ORFK3g+-Wu+2O${@y~Sy+~hh+t)W6x zv9L1`+GT0kT^qE)9;R`VLB&{4{hHa)m1CX+>9+))_(eYv{PkWztE4mN(SyhCt?fYWShIsVi~- zo@RNYym9%yML6k~@wD>-KDe^HbvX&_G#Vi@i(}R2WhTNZ{QQZFIt<~56^f`L^)!aL)@4tHM%B9t- zi`9rf{}mCaM~l(w8?Tj#YH^&-q!UV1R+A?)A<^{4Qt@menSms3B6XVW0v3?+N}4jQ zu`cMaZUmS-vJiq^0Bgqqz+CrfRn{gT&?I9MDQ3kh)Z-c+GRS*fEOpxSSU)fu%Rfp- zlcto8%F`Uqd|%DMhKxcMB#o=_xam=*fkI}3z=A!3U<)!6OwVaWJvpI;T1|H*3kfUt z?WS8(wYXx^lS(R~Xl#a|pEBtvQg1(6$xYR-hdQ?a*ll#Pru2&o$~TdkVDApnW>+LzMrV z{|&W3gOKRyG`QNf<+r|t(c+%7#h!tZTWlY^Ljc@Ekdx;9B@b!v&-<;^`ohH0vyccD z=%7Idbvg*_oS|eMA~OsP8+2Hw!~ffmzWqUc@Gzfu#GprXdZcRJR}8jn{?)#PcB7@Y zM1+Q6!GgJiMPKv$4{!K_E56`D%hK>i?86z|7cBUO4BwE>Yng4w3hlUXYH4Hs)D?DJ z1RWLVF@qk{>9N(;&O&RK(b@$p}&Fn!1u60L9oMoO8W|Jzwp4qkWSkRw9BAfI_+|JUHH+$DIHmc z3>wnyTAyj7LE)*mdmJ_$Gwo?%61rBAg<0^fF|l%Q1V8RX@0uL5f_38gS&_#PXJo01>CrM*|R=oL5!%%I2@Lk7og5~fwmLN)_ZT+3+Wckq6h!%gLhYRZ+?2^)laX? z-CBP4*4rQ6dMnSpk4a`-ef{HE)Y;$j2fq+@p+5rS&nlU4$j1%=o{b>j$vMx)G2dhd z0GJ*%nNgU=hOpy06dp0%(Q$Ad>@boX0T6Oqe!zz}U^N=&*FLk^?%DS}({Fnri(sSE zwJ9>V8$m3V??C2||6?lIx6VzW7tE{xm?LnGb=n3;{=!fJZ+h4)hW0FPF+xYKcmAW- zI6AI_ZTO144=#W2M(@6r-hGAM14i$G0^ObS>zj9%4GfLr!qe~Fcd<3U$><*{4m_dv z|G=rmff2p`m{W@bLwf&Frxphe>HSYSwbUT>hXt^VJ49-DO1Q^i$$~y`O6c3(7%*D+ z#b957?l&mj4Xnz|C*)zRdOCqW!;r~shSDWJTgr5-}!uSmj!myf9 ztjHvePVp6SsZ3Wioi-`XkEc>;76gVCYfPTLppRSEq5UihU9{}XH2@`-AP7aWNw;f} zY}RXQk@)BMQzT7u{3%Jz0ti(P?jY`7WuUVg>FPmlc>d5G#NVq7J}nT*mz!O2wd=0- mVq+k;>y_^L?zw|S$@}t?FFg5+@Jr!2{*>HA>Hr!p+ self.comfortable_temperature_range[1]: - - self.current_temperature -= 1 - - def adjust_humidity(self): - if not self.comfortable_humidity_range[0] <= self.current_humidity <= self.comfortable_humidity_range[1]: - if self.current_humidity < self.comfortable_humidity_range[0]: - - self.current_humidity += 5 - elif self.current_humidity > self.comfortable_humidity_range[1]: - - self.current_humidity -= 5 + self.comfortable_temperature_range = (20, 24) # 添加舒适温度范围 + self.comfortable_humidity_range = (40, 60) # 添加舒适湿度范围 + self.reset_conditions() - def display_status(self): - print(f"当前温度: {self.current_temperature:.1f}°C, 当前湿度: {self.current_humidity:.1f}%") + def reset_conditions(self): + self.current_temperature = random.uniform(-12, 42) + self.current_humidity = random.uniform(0, 100) - def main_loop(self, root): # 接受root参数 + def adjust(self): + self.reset_conditions() # 获取新的初始温度和湿度 if not self.comfortable_temperature_range[0] <= self.current_temperature <= self.comfortable_temperature_range[1]: - self.adjust_temperature() + self.current_temperature = random.uniform(*self.comfortable_temperature_range) if not self.comfortable_humidity_range[0] <= self.current_humidity <= self.comfortable_humidity_range[1]: - self.adjust_humidity() - - if not ( - self.comfortable_temperature_range[0] <= self.current_temperature <= self.comfortable_temperature_range[1] - and - self.comfortable_humidity_range[0] <= self.current_humidity <= self.comfortable_humidity_range[1] - ): - self.display_status() - root.after(1000, self.main_loop, root) # 使用after而非sleep - else: - print("温度和湿度均在舒适范围内,停止调节。") - print(f"温度: {self.current_temperature:.1f}°C, 湿度: {self.current_humidity:.1f}%") - # 可能需要在这里调用一次update_gui以最终更新GUI显示结果 - # self.app.update_gui_final() 如果在ACApp类中实现了这个方法来显示最终状态 - + self.current_humidity = random.uniform(*self.comfortable_humidity_range) + return self.current_temperature, self.current_humidity # 返回调节后的温度和湿度 class ACApp(tk.Tk): def __init__(self): super().__init__() self.title("空调自动调节系统") - self.geometry("800x600") # 调整窗口大小以适应内容 + self.geometry("800x600") - # 创建Treeview表格 - self.treeview = ttk.Treeview(self, columns=("编号", "初始温度", "初始湿度", "调节后温度", "调节后湿度"), + self.treeview = ttk.Treeview(self, + columns=("编号", "初始温度", "初始湿度", "调节后温度", "调节后湿度"), show="headings") self.treeview.heading("编号", text="编号") self.treeview.heading("初始温度", text="初始温度") self.treeview.heading("初始湿度", text="初始湿度") self.treeview.heading("调节后温度", text="调节后温度") self.treeview.heading("调节后湿度", text="调节后湿度") - self.treeview.column("编号", width=50, anchor=tk.CENTER) - self.treeview.column("初始温度", width=80, anchor=tk.CENTER) - self.treeview.column("初始湿度", width=80, anchor=tk.CENTER) - self.treeview.column("调节后温度", width=80, anchor=tk.CENTER) - self.treeview.column("调节后湿度", width=80, anchor=tk.CENTER) + for col in self.treeview['columns']: + self.treeview.column(col, width=80, anchor=tk.CENTER) self.treeview.grid(row=0, column=0, columnspan=4, padx=10, pady=10) self.aircon = AirConditioner() - self.line_number = 1 # 初始化行编号 - self.is_adjusting = True # 添加标志位,判断是否仍在调节过程中 - self.update_gui() # 先更新一次GUI - self.aircon.main_loop(self) # 传递self给main_loop以便使用after方法 - - self.treeview.pack(expand=True, fill=tk.BOTH, padx=10, pady=10) # 让Treeview自适应填充空间 - self.rowconfigure(0, weight=1) # 让树状视图所在的行填充额外空间 - self.columnconfigure(0, weight=1) # 让树状视图所在的列填充额外空间 - def update_gui(self): - if self.is_adjusting: # 只在调节过程中更新数据 - # 更新Treeview中的数据,这里假设初始数据就是当前数据,实际应用中可能需要记录调节前的实际初始值 - self.treeview.insert("", tk.END, values=(self.line_number, - f"{self.aircon.current_temperature:.1f}°C", - f"{self.aircon.current_humidity:.1f}%", - f"{self.aircon.current_temperature:.1f}°C", - f"{self.aircon.current_humidity:.1f}%")) - self.line_number += 1 - else: # 调节完成后,添加最终状态 - if self.line_number == 1: # 如果还没有插入过数据,则插入第一行 - self.treeview.insert("", tk.END, values=(self.line_number, - f"{self.aircon.current_temperature:.1f}°C", - f"{self.aircon.current_humidity:.1f}%", - f"{self.aircon.current_temperature:.1f}°C", - f"{self.aircon.current_humidity:.1f}%")) - self.line_number += 1 - print("温度和湿度均在舒适范围内,停止调节。") - print(f"温度: {self.current_temperature:.1f}°C, 湿度: {self.current_humidity:.1f}%") - self.is_adjusting = False # 设置标志位为False,停止调节后的数据更新 - - def main_loop(self): - if self.is_adjusting: - # 新增模拟环境变化 - self.aircon.simulate_environment_change() - - if not self.comfortable_temperature_range[0] <= self.current_temperature <= self.comfortable_temperature_range[1]: - self.adjust_temperature() - if not self.comfortable_humidity_range[0] <= self.current_humidity <= self.comfortable_humidity_range[1]: - self.adjust_humidity() - - if not ( - self.comfortable_temperature_range[0] <= self.current_temperature <= self.comfortable_temperature_range[1] - and - self.comfortable_humidity_range[0] <= self.current_humidity <= self.comfortable_humidity_range[1] - ): - self.display_status() - self.after(1000, self.main_loop) # 继续循环 - else: - self.is_adjusting = False - self.update_gui_final() # 假设这里调用最后的更新GUI方法 - else: - pass # 已经调整完毕,无需操作 - + self.line_number = 0 + self.is_adjusted = False + self.update_interval = 5000 # 每5秒更新一次 + self.schedule_update() # 安排首次更新 + + self.treeview.pack(fill=tk.BOTH, expand=True, padx=10, pady=10) + self.rowconfigure(0, weight=1) + self.columnconfigure(0, weight=1) + + def schedule_update(self): + """计划下一次更新""" + self.line_number += 1 + initial_temp, initial_humidity = self.aircon.current_temperature, self.aircon.current_humidity + adjusted_temp, adjusted_humidity = self.aircon.adjust() + self.treeview.insert("", tk.END, values=(self.line_number, + f"{initial_temp:.1f}°C", + f"{initial_humidity:.1f}%", + f"{adjusted_temp:.1f}°C", + f"{adjusted_humidity:.1f}%")) + # 安排下一次更新 + self.after(self.update_interval, self.schedule_update) if __name__ == "__main__": app = ACApp() diff --git a/计科2101 雷浩 21412030125.doc b/计科2101 雷浩 21412030125.doc index 2f2b2b4aeb05b679a60d9060ea6603a2c5c4aa79..54316ad980ec214827030732766807644b3f9a2e 100644 GIT binary patch delta 46243 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 delta 19979 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