训练图片管理面板,右侧统计从前十限制改为全部,并且支持点击直接显示。
This commit is contained in:
@@ -96,6 +96,7 @@ class DataManagementApp:
|
|||||||
on_download_history_callback=self._on_download_history,
|
on_download_history_callback=self._on_download_history,
|
||||||
on_export_callback=self._on_export,
|
on_export_callback=self._on_export,
|
||||||
on_settings_callback=self._on_settings,
|
on_settings_callback=self._on_settings,
|
||||||
|
on_item_click_callback=lambda name: self.filter_panel.set_goods_name_and_query(name),
|
||||||
width=RIGHT_PANEL_WIDTH
|
width=RIGHT_PANEL_WIDTH
|
||||||
)
|
)
|
||||||
self.statistics_panel.pack(side="right", fill="y", padx=(5, 0))
|
self.statistics_panel.pack(side="right", fill="y", padx=(5, 0))
|
||||||
|
|||||||
@@ -270,7 +270,7 @@ class MySQLManager:
|
|||||||
month_start = today_start.replace(day=1)
|
month_start = today_start.replace(day=1)
|
||||||
month_count = base_query.filter(Model.create_time >= month_start).count()
|
month_count = base_query.filter(Model.create_time >= month_start).count()
|
||||||
|
|
||||||
# TOP 10物品统计
|
# 全部物品统计(按数量降序)
|
||||||
from sqlalchemy import func
|
from sqlalchemy import func
|
||||||
top_items = session.query(
|
top_items = session.query(
|
||||||
Model.goods_name,
|
Model.goods_name,
|
||||||
@@ -289,7 +289,6 @@ class MySQLManager:
|
|||||||
|
|
||||||
top_items = top_items.group_by(Model.goods_name)\
|
top_items = top_items.group_by(Model.goods_name)\
|
||||||
.order_by(func.count(Model.id).desc())\
|
.order_by(func.count(Model.id).desc())\
|
||||||
.limit(10)\
|
|
||||||
.all()
|
.all()
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -276,3 +276,9 @@ class FilterPanel(ctk.CTkFrame):
|
|||||||
self.query_button.configure(state="disabled", text="查询中...")
|
self.query_button.configure(state="disabled", text="查询中...")
|
||||||
else:
|
else:
|
||||||
self.query_button.configure(state="normal", text="查询")
|
self.query_button.configure(state="normal", text="查询")
|
||||||
|
|
||||||
|
def set_goods_name_and_query(self, goods_name: str):
|
||||||
|
"""从排行榜点击物品名称时,填入筛选框并触发查询"""
|
||||||
|
self.goods_search_entry.delete(0, 'end')
|
||||||
|
self.goods_search_entry.insert(0, goods_name)
|
||||||
|
self._on_query()
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ class StatisticsPanel(ctk.CTkFrame):
|
|||||||
on_download_history_callback: Callable,
|
on_download_history_callback: Callable,
|
||||||
on_export_callback: Callable,
|
on_export_callback: Callable,
|
||||||
on_settings_callback: Callable,
|
on_settings_callback: Callable,
|
||||||
|
on_item_click_callback: Optional[Callable] = None,
|
||||||
**kwargs
|
**kwargs
|
||||||
):
|
):
|
||||||
super().__init__(parent, **kwargs)
|
super().__init__(parent, **kwargs)
|
||||||
@@ -23,6 +24,7 @@ class StatisticsPanel(ctk.CTkFrame):
|
|||||||
self.on_download_history_callback = on_download_history_callback
|
self.on_download_history_callback = on_download_history_callback
|
||||||
self.on_export_callback = on_export_callback
|
self.on_export_callback = on_export_callback
|
||||||
self.on_settings_callback = on_settings_callback
|
self.on_settings_callback = on_settings_callback
|
||||||
|
self.on_item_click_callback = on_item_click_callback
|
||||||
|
|
||||||
self._create_widgets()
|
self._create_widgets()
|
||||||
|
|
||||||
@@ -130,13 +132,13 @@ class StatisticsPanel(ctk.CTkFrame):
|
|||||||
separator2 = ctk.CTkFrame(time_frame, height=2)
|
separator2 = ctk.CTkFrame(time_frame, height=2)
|
||||||
separator2.pack(fill="x", pady=10, padx=15)
|
separator2.pack(fill="x", pady=10, padx=15)
|
||||||
|
|
||||||
# ==================== TOP 10物品排行 ====================
|
# ==================== 物品排行(全部) ====================
|
||||||
top_frame = ctk.CTkFrame(self)
|
top_frame = ctk.CTkFrame(self)
|
||||||
top_frame.pack(fill="both", expand=True, padx=15, pady=(0, 10))
|
top_frame.pack(fill="both", expand=True, padx=15, pady=(0, 10))
|
||||||
|
|
||||||
top_title = ctk.CTkLabel(
|
top_title = ctk.CTkLabel(
|
||||||
top_frame,
|
top_frame,
|
||||||
text="TOP 10 物品排行",
|
text="物品排行(全部)",
|
||||||
font=("Arial", 12, "bold")
|
font=("Arial", 12, "bold")
|
||||||
)
|
)
|
||||||
top_title.pack(pady=(10, 5), padx=10)
|
top_title.pack(pady=(10, 5), padx=10)
|
||||||
@@ -212,7 +214,7 @@ class StatisticsPanel(ctk.CTkFrame):
|
|||||||
- today_count: 今日数量
|
- today_count: 今日数量
|
||||||
- week_count: 本周数量
|
- week_count: 本周数量
|
||||||
- month_count: 本月数量
|
- month_count: 本月数量
|
||||||
- top_items: TOP 10列表 [{'name': str, 'count': int}, ...]
|
- top_items: 全部物品列表 [{'name': str, 'count': int}, ...]
|
||||||
"""
|
"""
|
||||||
# 查询结果
|
# 查询结果
|
||||||
total_count = stats.get('total_count', 0)
|
total_count = stats.get('total_count', 0)
|
||||||
@@ -232,7 +234,7 @@ class StatisticsPanel(ctk.CTkFrame):
|
|||||||
self._update_top_items(stats.get('top_items', []))
|
self._update_top_items(stats.get('top_items', []))
|
||||||
|
|
||||||
def _update_top_items(self, top_items: list):
|
def _update_top_items(self, top_items: list):
|
||||||
"""更新TOP 10排行榜"""
|
"""更新物品排行(全部)"""
|
||||||
# 清空现有内容
|
# 清空现有内容
|
||||||
for widget in self.top_scroll.winfo_children():
|
for widget in self.top_scroll.winfo_children():
|
||||||
widget.destroy()
|
widget.destroy()
|
||||||
@@ -247,7 +249,7 @@ class StatisticsPanel(ctk.CTkFrame):
|
|||||||
no_data_label.pack(pady=10)
|
no_data_label.pack(pady=10)
|
||||||
return
|
return
|
||||||
|
|
||||||
# 显示TOP 10
|
# 显示全部物品
|
||||||
for i, item in enumerate(top_items, 1):
|
for i, item in enumerate(top_items, 1):
|
||||||
item_frame = ctk.CTkFrame(self.top_scroll)
|
item_frame = ctk.CTkFrame(self.top_scroll)
|
||||||
item_frame.pack(fill="x", pady=2, padx=5)
|
item_frame.pack(fill="x", pady=2, padx=5)
|
||||||
@@ -261,15 +263,32 @@ class StatisticsPanel(ctk.CTkFrame):
|
|||||||
)
|
)
|
||||||
rank_label.pack(side="left", padx=(5, 2))
|
rank_label.pack(side="left", padx=(5, 2))
|
||||||
|
|
||||||
# 物品名称
|
# 物品名称(可点击筛选)
|
||||||
name_label = ctk.CTkLabel(
|
name_label = ctk.CTkLabel(
|
||||||
item_frame,
|
item_frame,
|
||||||
text=item['name'],
|
text=item['name'],
|
||||||
font=("Arial", 10),
|
font=("Arial", 10),
|
||||||
anchor="w"
|
anchor="w",
|
||||||
|
cursor="hand2" # 鼠标悬浮时显示手型
|
||||||
)
|
)
|
||||||
name_label.pack(side="left", fill="x", expand=True, padx=5)
|
name_label.pack(side="left", fill="x", expand=True, padx=5)
|
||||||
|
|
||||||
|
# 绑定点击与悬浮事件
|
||||||
|
if self.on_item_click_callback:
|
||||||
|
item_name = item['name']
|
||||||
|
name_label.bind(
|
||||||
|
"<Button-1>",
|
||||||
|
lambda e, name=item_name: self.on_item_click_callback(name)
|
||||||
|
)
|
||||||
|
name_label.bind(
|
||||||
|
"<Enter>",
|
||||||
|
lambda e, lbl=name_label: lbl.configure(text_color="#4FC3F7")
|
||||||
|
)
|
||||||
|
name_label.bind(
|
||||||
|
"<Leave>",
|
||||||
|
lambda e, lbl=name_label: lbl.configure(text_color=ctk.ThemeManager.theme["CTkLabel"]["text_color"])
|
||||||
|
)
|
||||||
|
|
||||||
# 数量
|
# 数量
|
||||||
count_label = ctk.CTkLabel(
|
count_label = ctk.CTkLabel(
|
||||||
item_frame,
|
item_frame,
|
||||||
@@ -291,6 +310,6 @@ class StatisticsPanel(ctk.CTkFrame):
|
|||||||
self.week_label.configure(text="本周: 0 张")
|
self.week_label.configure(text="本周: 0 张")
|
||||||
self.month_label.configure(text="本月: 0 张")
|
self.month_label.configure(text="本月: 0 张")
|
||||||
|
|
||||||
# 清空TOP 10
|
# 清空全部物品排行
|
||||||
for widget in self.top_scroll.winfo_children():
|
for widget in self.top_scroll.winfo_children():
|
||||||
widget.destroy()
|
widget.destroy()
|
||||||
|
|||||||
Reference in New Issue
Block a user