Python 写的 《监控视频存储计算器》

news/2024/12/21 20:43:36/

代码: 

python">import tkinter as tk
from tkinter import ttk
import math
from tkinter.font import Fontclass StorageCalculator:def __init__(self, root):self.root = rootself.root.title("监控视频存储计算器")self.root.geometry("600x800")self.root.configure(bg='#f0f0f0')# 设置主题和样式self.style = ttk.Style()self.style.theme_use('clam')  # 使用clam主题作为基础# 定义颜色方案self.colors = {'primary': '#2196F3',    # 主色调'secondary': '#64B5F6',   # 次要色调'bg': '#f0f0f0',         # 背景色'text': '#212121',       # 文字颜色'success': '#4CAF50'     # 成功色}# 设置自定义字体self.title_font = Font(family="微软雅黑", size=12, weight="bold")self.normal_font = Font(family="微软雅黑", size=10)self.result_font = Font(family="微软雅黑", size=11, weight="bold")# 配置样式self.style.configure('Title.TLabel', font=self.title_font, background=self.colors['bg'],foreground=self.colors['primary'])self.style.configure('Normal.TLabel', font=self.normal_font,background=self.colors['bg'])self.style.configure('Custom.TButton',font=self.normal_font,background=self.colors['primary'],padding=(20, 10))self.style.configure('Tab.TNotebook',background=self.colors['bg'])self.style.configure('Result.TLabelframe',background=self.colors['bg'])# 创建主标题self.create_header()# 创建notebookself.notebook = ttk.Notebook(root, style='Tab.TNotebook')self.notebook.pack(fill='both', expand=True, padx=20, pady=(0, 20))# 创建计算页面self.create_forward_page()self.create_reverse_page()# 创建页脚self.create_footer()def create_header(self):"""创建头部标题区域"""header_frame = ttk.Frame(self.root)header_frame.pack(fill='x', padx=20, pady=20)title = ttk.Label(header_frame, text="监控视频存储计算器",style='Title.TLabel')title.pack()subtitle = ttk.Label(header_frame,text="专业的存储空间评估工具",style='Normal.TLabel')subtitle.pack()def create_forward_page(self):"""创建正向计算页面"""self.forward_frame = ttk.Frame(self.notebook, padding="20")self.notebook.add(self.forward_frame, text=" 计算存储需求 ")# 创建输入区域input_frame = ttk.LabelFrame(self.forward_frame, text="参数输入",padding="15")input_frame.pack(fill='x', padx=10, pady=5)# 添加输入控件self.create_input_field(input_frame, "摄像头数量:", 0, self.normal_font)self.cameras = self.entryself.create_input_field(input_frame, "每天录像时间(小时):", 1, self.normal_font)self.hours = self.entryself.hours.insert(0, "24")  # 默认24小时self.create_input_field(input_frame, "需要保存的天数:", 2, self.normal_font)self.days = self.entry# 摄像头类型选择ttk.Label(input_frame, text="摄像头类型:", font=self.normal_font).grid(row=3, column=0, sticky=tk.W, pady=5)self.camera_type = ttk.Combobox(input_frame, width=25,font=self.normal_font)self.camera_type['values'] = ['200万像素', '300万像素', '400万像素', '500万像素']self.camera_type.current(0)self.camera_type.grid(row=3, column=1, sticky=tk.W, pady=5)# 编码方式选择ttk.Label(input_frame, text="编码方式:", font=self.normal_font).grid(row=4, column=0, sticky=tk.W, pady=5)self.encoding = ttk.Combobox(input_frame, width=25,font=self.normal_font)self.encoding['values'] = ['H.264', 'H.265']self.encoding.current(1)  # 默认H.265self.encoding.grid(row=4, column=1, sticky=tk.W, pady=5)# 计算按钮btn_frame = ttk.Frame(self.forward_frame)btn_frame.pack(fill='x', pady=20)calc_btn = ttk.Button(btn_frame, text="计算存储需求",style='Custom.TButton',command=self.calculate_forward)calc_btn.pack(expand=True)# 结果显示区域self.forward_result_frame = ttk.LabelFrame(self.forward_frame,text="计算结果",padding="15",style='Result.TLabelframe')self.forward_result_frame.pack(fill='x', padx=10, pady=5)self.storage_label = ttk.Label(self.forward_result_frame,text="",font=self.result_font)self.storage_label.pack(anchor=tk.W)self.recommendation_label = ttk.Label(self.forward_result_frame,text="",font=self.result_font)self.recommendation_label.pack(anchor=tk.W)def create_reverse_page(self):"""创建反向计算页面"""self.reverse_frame = ttk.Frame(self.notebook, padding="20")self.notebook.add(self.reverse_frame, text=" 计算存储时间 ")# 创建输入区域input_frame = ttk.LabelFrame(self.reverse_frame,text="参数输入",padding="15")input_frame.pack(fill='x', padx=10, pady=5)# 添加输入控件self.create_input_field(input_frame, "硬盘容量(TB):", 0, self.normal_font)self.storage_size = self.entryself.create_input_field(input_frame, "摄像头数量:", 1, self.normal_font)self.rev_cameras = self.entryself.create_input_field(input_frame, "每天录像时间(小时):", 2, self.normal_font)self.rev_hours = self.entry# 摄像头类型选择ttk.Label(input_frame, text="摄像头类型:",font=self.normal_font).grid(row=3, column=0,sticky=tk.W, pady=5)self.rev_camera_type = ttk.Combobox(input_frame, width=25,font=self.normal_font)self.rev_camera_type['values'] = ['200万像素', '300万像素', '400万像素', '500万像素']self.rev_camera_type.current(0)self.rev_camera_type.grid(row=3, column=1, sticky=tk.W, pady=5)# 编码方式选择ttk.Label(input_frame, text="编码方式:",font=self.normal_font).grid(row=4, column=0,sticky=tk.W, pady=5)self.rev_encoding = ttk.Combobox(input_frame, width=25,font=self.normal_font)self.rev_encoding['values'] = ['H.264', 'H.265']self.rev_encoding.current(1)  # 默认H.265self.rev_encoding.grid(row=4, column=1, sticky=tk.W, pady=5)# 计算按钮btn_frame = ttk.Frame(self.reverse_frame)btn_frame.pack(fill='x', pady=20)calc_btn = ttk.Button(btn_frame,text="计算可存储天数",style='Custom.TButton',command=self.calculate_reverse)calc_btn.pack(expand=True)# 结果显示区域self.reverse_result_frame = ttk.LabelFrame(self.reverse_frame,text="计算结果",padding="15",style='Result.TLabelframe')self.reverse_result_frame.pack(fill='x', padx=10, pady=5)self.days_label = ttk.Label(self.reverse_result_frame,text="",font=self.result_font)self.days_label.pack(anchor=tk.W)def create_footer(self):"""创建页脚"""footer = ttk.Label(self.root,text="© 2024 专业视频监控存储解决方案",style='Normal.TLabel')footer.pack(pady=10)def create_input_field(self, parent, label_text, row, font):"""创建统一的输入字段"""ttk.Label(parent, text=label_text,font=font).grid(row=row, column=0,sticky=tk.W, pady=5)self.entry = ttk.Entry(parent, width=25,font=font)self.entry.grid(row=row, column=1, sticky=tk.W, pady=5)return self.entrydef calculate_storage(self, cameras, hours_per_day, days, camera_type, encoding):"""计算存储需求camera_type: 摄像头类型 (200万/300万/400万/500万)encoding: 编码方式 (H.264/H.265)"""# 每天存储空间(GB)daily_storage = {'200万像素': {'H.264': 42.19,  # 4096kbps'H.265': 21.09   # 2048kbps},'300万像素': {'H.264': 42.19,  # 4096kbps'H.265': 21.09   # 2048kbps},'400万像素': {'H.264': 42.19,  # 4096kbps'H.265': 21.09   # 2048kbps},'500万像素': {'H.264': 63.28,  # 6144kbps'H.265': 31.64   # 3072kbps}}# 计算单个摄像头每天实际存储量daily_per_camera = daily_storage[camera_type][encoding] * (hours_per_day / 24)# 计算总存储量total_storage_gb = daily_per_camera * cameras * days# 转换为TB并返回return round(total_storage_gb / 1024, 2)def calculate_days(self, storage_tb, cameras, hours_per_day, camera_type, encoding):"""计算可存储天数"""daily_storage = {'200万像素': {'H.264': 42.19,'H.265': 21.09},'300万像素': {'H.264': 42.19,'H.265': 21.09},'400万像素': {'H.264': 42.19,'H.265': 21.09},'500万像素': {'H.264': 63.28,'H.265': 31.64}}# 计算单个摄像头每天实际存储量daily_per_camera = daily_storage[camera_type][encoding] * (hours_per_day / 24)# 计算可存储天数total_gb = storage_tb * 1024days = total_gb / (daily_per_camera * cameras)return round(days, 1)def calculate_forward(self):try:cameras = int(self.cameras.get())hours = float(self.hours.get())days = int(self.days.get())camera_type = self.camera_type.get()encoding = self.encoding.get()if cameras <= 0 or hours <= 0 or days <= 0:raise ValueError("请输入大于0的数值")# 获取单个摄像头每天的存储量daily_storage = {'200万像素': {'H.264': 42.19,'H.265': 21.09},'300万像素': {'H.264': 42.19,'H.265': 21.09},'400万像素': {'H.264': 42.19,'H.265': 21.09},'500万像素': {'H.264': 63.28,'H.265': 31.64}}daily_per_camera = daily_storage[camera_type][encoding] * (hours / 24)daily_total = daily_per_camera * camerasstorage = self.calculate_storage(cameras, hours, days, camera_type, encoding)self.storage_label.config(text=f"每天存储空间: {round(daily_total, 2)} GB/天\n"f"总存储容量: {storage} TB",foreground=self.colors['success'])self.recommendation_label.config(text=f"建议配置: {math.ceil(storage)} TB 硬盘\n"f"(基于{camera_type}摄像头,{encoding}编码)\n"f"单个摄像头: {round(daily_per_camera, 2)} GB/天",foreground=self.colors['success'])except ValueError as e:self.storage_label.config(text="输入错误!",foreground='red')self.recommendation_label.config(text="请检查输入的数值是否正确",foreground='red')def calculate_reverse(self):try:storage = float(self.storage_size.get())cameras = int(self.rev_cameras.get())hours = float(self.rev_hours.get())camera_type = self.rev_camera_type.get()encoding = self.rev_encoding.get()if storage <= 0 or cameras <= 0 or hours <= 0:raise ValueError("请输入大于0的数值")# 获取单个摄像头每天的存储量daily_storage = {'200万像素': {'H.264': 42.19,'H.265': 21.09},'300万像素': {'H.264': 42.19,'H.265': 21.09},'400万像素': {'H.264': 42.19,'H.265': 21.09},'500万像素': {'H.264': 63.28,'H.265': 31.64}}daily_per_camera = daily_storage[camera_type][encoding] * (hours / 24)daily_total = daily_per_camera * camerasdays = self.calculate_days(storage, cameras, hours, camera_type, encoding)self.days_label.config(text=f"每天存储空间: {round(daily_total, 2)} GB/天\n"f"单个摄像头: {round(daily_per_camera, 2)} GB/天\n"f"可存储天数: {days} 天\n"f"约等于 {round(days/30, 1)} 个月 或 {round(days/365, 1)} 年\n"f"(基于{camera_type}摄像头,{encoding}编码)",foreground=self.colors['success'])except ValueError as e:self.days_label.config(text="输入错误!\n请检查输入的数值是否正确",foreground='red')def main():root = tk.Tk()app = StorageCalculator(root)root.mainloop()if __name__ == "__main__":main()


http://www.ppmy.cn/news/1557012.html

相关文章

01背包:模板题+实战题

一、01背包的定义 我们有一个背包&#xff0c;背包的容积有限&#xff0c;最多只能装下总体积为V的物品。现在给定我们N个物品&#xff0c;第i个物品的体积vi&#xff0c;对应的价值是wi&#xff08; 1 ≤ i ≤ N 1 \leq i \leq N 1≤i≤N&#xff09;。每个物品有且仅有一个。…

【JavaWeb】Ajax

目录 一、什么是Ajax&#xff1f; 二、同步与异步 三、Ajax工作原理 四、Ajax实现步骤 五、Ajax应用场景 六、Ajax常见问题 1.缓存问题 2.跨域问题 3.请求超时与网络异常 4.取消请求 七、常见Ajax三种请求方式 1.jQuery请求 2.Axios请求 3.Fetch请求 一、什么是A…

mac编译ijkplayer遇到问题

问题&#xff1a;./init-android.sh git version 2.44.0 pull ffmpeg base : command not founde.sh: line 2: : command not founde.sh: line 5: : command not founde.sh: line 6: tools/pull-repo-base.sh: line 9: syntax error near unexpected token elif ools/pull-re…

【第九节】Git 服务器搭建

目录 前言 一、 使用裸存储库搭建 Git 服务器 1.1 安装 Git 1.2 创建裸存储库 1.3 配置 SSH 访问 1.4 克隆仓库 二、 使用 GitLab 搭建 Git 服务器 2.1 安装 GitLab 2.2 配置 GitLab 2.3 创建项目 2.4 生成 SSH 密钥 2.5 添加 SSH Key 三、 使用 GitLab 管理项目 …

智源大模型通用算子库FlagGems四大能力升级 持续赋能AI系统开源生态

FlagGems是由智源研究院于2024年6月推出的面向多种AI芯片的开源大模型通用算子库。FlagGems使用Triton语言开发&#xff0c;在Triton生态开源开放的基础上&#xff0c;为多种AI芯片提供开源、统一、高效的算子层生态接入方案。FlagGems沿着统一的中间语言、统一的算子接口和统一…

条款24:若所有参数皆需类型转换,请为此采用非成员函数

条款24&#xff1a;若所有参数皆需类型转换&#xff0c;请为此采用非成员函数 设计一个表示有理数的类时&#xff0c;允许从整数隐式转换为有理数是有用的&#xff1a; class Rational { public:Rational(int numerator 0, // 该构造函数没有explicit限制;int denominator …

linux下操作es及kibana的操作记录

背景&#xff1a;工作中后面开始用es和kibana了&#xff0c;为了方便后面的操作&#xff0c;特记录一下&#xff0c;好多命令实在是记不住了&#xff0c;&#x1f604; kibana的操作 1.查看所有的索引的命令 GET /_cat/indices2.创建索引的命令 PUT /es_dsj_6c_jky_yunzhe_…

【机器学习】机器学习的基本分类-强化学习-REINFORCE 算法

REINFORCE 算法 REINFORCE 是一种基于策略梯度的强化学习算法&#xff0c;直接通过采样环境中的轨迹来优化策略。它是策略梯度方法的基础实现&#xff0c;具有简单直观的优点。 核心思想 目标函数 最大化策略的期望回报&#xff1a; ​​​​​​​ …