增加了查看入库秤上传图片的GUI界面。
This commit is contained in:
@@ -0,0 +1,296 @@
|
||||
"""
|
||||
右侧统计面板
|
||||
"""
|
||||
import customtkinter as ctk
|
||||
from typing import Dict, Callable, Optional
|
||||
|
||||
|
||||
class StatisticsPanel(ctk.CTkFrame):
|
||||
"""右侧统计面板"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
parent,
|
||||
on_refresh_callback: Callable,
|
||||
on_download_history_callback: Callable,
|
||||
on_export_callback: Callable,
|
||||
on_settings_callback: Callable,
|
||||
**kwargs
|
||||
):
|
||||
super().__init__(parent, **kwargs)
|
||||
|
||||
self.on_refresh_callback = on_refresh_callback
|
||||
self.on_download_history_callback = on_download_history_callback
|
||||
self.on_export_callback = on_export_callback
|
||||
self.on_settings_callback = on_settings_callback
|
||||
|
||||
self._create_widgets()
|
||||
|
||||
def _create_widgets(self):
|
||||
"""创建UI组件"""
|
||||
# 标题
|
||||
title_label = ctk.CTkLabel(
|
||||
self,
|
||||
text="统计信息",
|
||||
font=("Arial", 16, "bold")
|
||||
)
|
||||
title_label.pack(pady=(15, 10), padx=15)
|
||||
|
||||
# ==================== 当前数据源信息 ====================
|
||||
datasource_frame = ctk.CTkFrame(self)
|
||||
datasource_frame.pack(fill="x", padx=15, pady=(0, 10))
|
||||
|
||||
datasource_title = ctk.CTkLabel(
|
||||
datasource_frame,
|
||||
text="当前数据源",
|
||||
font=("Arial", 12, "bold")
|
||||
)
|
||||
datasource_title.pack(pady=(10, 5), padx=10)
|
||||
|
||||
self.datasource_label = ctk.CTkLabel(
|
||||
datasource_frame,
|
||||
text="菜品",
|
||||
font=("Arial", 14, "bold"),
|
||||
text_color="blue"
|
||||
)
|
||||
self.datasource_label.pack(pady=(0, 10), padx=10)
|
||||
|
||||
# ==================== 数据统计 ====================
|
||||
stats_frame = ctk.CTkFrame(self)
|
||||
stats_frame.pack(fill="x", padx=15, pady=(0, 10))
|
||||
|
||||
stats_title = ctk.CTkLabel(
|
||||
stats_frame,
|
||||
text="数据统计",
|
||||
font=("Arial", 12, "bold")
|
||||
)
|
||||
stats_title.pack(pady=(10, 5), padx=10)
|
||||
|
||||
# 查询结果
|
||||
self.query_result_label = ctk.CTkLabel(
|
||||
stats_frame,
|
||||
text="查询结果: 0 张",
|
||||
font=("Arial", 11),
|
||||
anchor="w"
|
||||
)
|
||||
self.query_result_label.pack(fill="x", pady=2, padx=15)
|
||||
|
||||
# 已选择
|
||||
self.selected_label = ctk.CTkLabel(
|
||||
stats_frame,
|
||||
text="已选择: 0 张",
|
||||
font=("Arial", 11),
|
||||
anchor="w"
|
||||
)
|
||||
self.selected_label.pack(fill="x", pady=2, padx=15)
|
||||
|
||||
# 分隔线
|
||||
separator1 = ctk.CTkFrame(stats_frame, height=2)
|
||||
separator1.pack(fill="x", pady=10, padx=15)
|
||||
|
||||
# ==================== 时间分布 ====================
|
||||
time_frame = ctk.CTkFrame(self)
|
||||
time_frame.pack(fill="x", padx=15, pady=(0, 10))
|
||||
|
||||
time_title = ctk.CTkLabel(
|
||||
time_frame,
|
||||
text="时间分布",
|
||||
font=("Arial", 12, "bold")
|
||||
)
|
||||
time_title.pack(pady=(10, 5), padx=10)
|
||||
|
||||
# 今日
|
||||
self.today_label = ctk.CTkLabel(
|
||||
time_frame,
|
||||
text="今日: 0 张",
|
||||
font=("Arial", 11),
|
||||
anchor="w"
|
||||
)
|
||||
self.today_label.pack(fill="x", pady=2, padx=15)
|
||||
|
||||
# 本周
|
||||
self.week_label = ctk.CTkLabel(
|
||||
time_frame,
|
||||
text="本周: 0 张",
|
||||
font=("Arial", 11),
|
||||
anchor="w"
|
||||
)
|
||||
self.week_label.pack(fill="x", pady=2, padx=15)
|
||||
|
||||
# 本月
|
||||
self.month_label = ctk.CTkLabel(
|
||||
time_frame,
|
||||
text="本月: 0 张",
|
||||
font=("Arial", 11),
|
||||
anchor="w"
|
||||
)
|
||||
self.month_label.pack(fill="x", pady=2, padx=15)
|
||||
|
||||
# 分隔线
|
||||
separator2 = ctk.CTkFrame(time_frame, height=2)
|
||||
separator2.pack(fill="x", pady=10, padx=15)
|
||||
|
||||
# ==================== TOP 10物品排行 ====================
|
||||
top_frame = ctk.CTkFrame(self)
|
||||
top_frame.pack(fill="both", expand=True, padx=15, pady=(0, 10))
|
||||
|
||||
top_title = ctk.CTkLabel(
|
||||
top_frame,
|
||||
text="TOP 10 物品排行",
|
||||
font=("Arial", 12, "bold")
|
||||
)
|
||||
top_title.pack(pady=(10, 5), padx=10)
|
||||
|
||||
# 可滚动的排行榜
|
||||
self.top_scroll = ctk.CTkScrollableFrame(top_frame, height=200)
|
||||
self.top_scroll.pack(fill="both", expand=True, padx=10, pady=(0, 10))
|
||||
|
||||
# ==================== 快捷操作 ====================
|
||||
actions_frame = ctk.CTkFrame(self)
|
||||
actions_frame.pack(fill="x", padx=15, pady=(0, 15))
|
||||
|
||||
actions_title = ctk.CTkLabel(
|
||||
actions_frame,
|
||||
text="快捷操作",
|
||||
font=("Arial", 12, "bold")
|
||||
)
|
||||
actions_title.pack(pady=(10, 5), padx=10)
|
||||
|
||||
# 刷新按钮
|
||||
refresh_btn = ctk.CTkButton(
|
||||
actions_frame,
|
||||
text="🔄 刷新",
|
||||
command=self.on_refresh_callback,
|
||||
height=30
|
||||
)
|
||||
refresh_btn.pack(fill="x", padx=10, pady=2)
|
||||
|
||||
# 下载历史按钮
|
||||
history_btn = ctk.CTkButton(
|
||||
actions_frame,
|
||||
text="📜 下载历史",
|
||||
command=self.on_download_history_callback,
|
||||
height=30,
|
||||
fg_color="purple",
|
||||
hover_color="darkviolet"
|
||||
)
|
||||
history_btn.pack(fill="x", padx=10, pady=2)
|
||||
|
||||
# 导出按钮
|
||||
export_btn = ctk.CTkButton(
|
||||
actions_frame,
|
||||
text="📊 导出数据",
|
||||
command=self.on_export_callback,
|
||||
height=30,
|
||||
fg_color="orange",
|
||||
hover_color="darkorange"
|
||||
)
|
||||
export_btn.pack(fill="x", padx=10, pady=2)
|
||||
|
||||
# 设置按钮
|
||||
settings_btn = ctk.CTkButton(
|
||||
actions_frame,
|
||||
text="⚙️ 设置",
|
||||
command=self.on_settings_callback,
|
||||
height=30,
|
||||
fg_color="gray",
|
||||
hover_color="darkgray"
|
||||
)
|
||||
settings_btn.pack(fill="x", padx=10, pady=(2, 10))
|
||||
|
||||
def update_datasource(self, datasource: str):
|
||||
"""更新当前数据源显示"""
|
||||
self.datasource_label.configure(text=datasource)
|
||||
|
||||
def update_statistics(self, stats: Dict):
|
||||
"""
|
||||
更新统计信息
|
||||
|
||||
Args:
|
||||
stats: 统计数据字典,包含:
|
||||
- total_count: 总数量
|
||||
- today_count: 今日数量
|
||||
- week_count: 本周数量
|
||||
- month_count: 本月数量
|
||||
- top_items: TOP 10列表 [{'name': str, 'count': int}, ...]
|
||||
"""
|
||||
# 查询结果
|
||||
total_count = stats.get('total_count', 0)
|
||||
self.query_result_label.configure(text=f"查询结果: {total_count} 张")
|
||||
|
||||
# 时间分布
|
||||
today_count = stats.get('today_count', 0)
|
||||
self.today_label.configure(text=f"今日: {today_count} 张")
|
||||
|
||||
week_count = stats.get('week_count', 0)
|
||||
self.week_label.configure(text=f"本周: {week_count} 张")
|
||||
|
||||
month_count = stats.get('month_count', 0)
|
||||
self.month_label.configure(text=f"本月: {month_count} 张")
|
||||
|
||||
# TOP 10排行
|
||||
self._update_top_items(stats.get('top_items', []))
|
||||
|
||||
def _update_top_items(self, top_items: list):
|
||||
"""更新TOP 10排行榜"""
|
||||
# 清空现有内容
|
||||
for widget in self.top_scroll.winfo_children():
|
||||
widget.destroy()
|
||||
|
||||
if not top_items:
|
||||
no_data_label = ctk.CTkLabel(
|
||||
self.top_scroll,
|
||||
text="暂无数据",
|
||||
font=("Arial", 11),
|
||||
text_color="gray"
|
||||
)
|
||||
no_data_label.pack(pady=10)
|
||||
return
|
||||
|
||||
# 显示TOP 10
|
||||
for i, item in enumerate(top_items, 1):
|
||||
item_frame = ctk.CTkFrame(self.top_scroll)
|
||||
item_frame.pack(fill="x", pady=2, padx=5)
|
||||
|
||||
# 排名
|
||||
rank_label = ctk.CTkLabel(
|
||||
item_frame,
|
||||
text=f"{i}.",
|
||||
font=("Arial", 11, "bold"),
|
||||
width=30
|
||||
)
|
||||
rank_label.pack(side="left", padx=(5, 2))
|
||||
|
||||
# 物品名称
|
||||
name_label = ctk.CTkLabel(
|
||||
item_frame,
|
||||
text=item['name'],
|
||||
font=("Arial", 10),
|
||||
anchor="w"
|
||||
)
|
||||
name_label.pack(side="left", fill="x", expand=True, padx=5)
|
||||
|
||||
# 数量
|
||||
count_label = ctk.CTkLabel(
|
||||
item_frame,
|
||||
text=f"{item['count']}张",
|
||||
font=("Arial", 10),
|
||||
text_color="blue"
|
||||
)
|
||||
count_label.pack(side="right", padx=5)
|
||||
|
||||
def update_selected_count(self, count: int):
|
||||
"""更新已选择数量"""
|
||||
self.selected_label.configure(text=f"已选择: {count} 张")
|
||||
|
||||
def clear_statistics(self):
|
||||
"""清空统计信息"""
|
||||
self.query_result_label.configure(text="查询结果: 0 张")
|
||||
self.selected_label.configure(text="已选择: 0 张")
|
||||
self.today_label.configure(text="今日: 0 张")
|
||||
self.week_label.configure(text="本周: 0 张")
|
||||
self.month_label.configure(text="本月: 0 张")
|
||||
|
||||
# 清空TOP 10
|
||||
for widget in self.top_scroll.winfo_children():
|
||||
widget.destroy()
|
||||
Reference in New Issue
Block a user