import gradio as gr import datetime import pandas as pd import json import os # 數據存儲文件 data_file = "dog_activity_data.json" # 初始化數據文件 def init_data_file(): if not os.path.exists(data_file): with open(data_file, "w") as file: json.dump([], file) # 加載活動記錄 def load_data(): try: with open(data_file, "r") as file: return json.load(file) except: return [] # 保存活動記錄 def save_activity(activity): timestamp = datetime.datetime.now() record = {"活動": activity, "時間": timestamp.strftime("%Y-%m-%d %H:%M:%S")} data = load_data() data.append(record) with open(data_file, "w") as file: json.dump(data, file) return update_activity_display() # 更新顯示活動記錄 (增加索引列) def update_activity_display(show_all=False): data = load_data() if not data: return pd.DataFrame(columns=["No.", "活動", "時間"]) # 添加索引列 df = pd.DataFrame(data) df.insert(0, "#(行號)", range(0, len(df))) if not show_all: df = df.tail(5) # 顯示最近 5 條 return df # 刪除記錄功能 def delete_activity(row_index): data = load_data() try: row_index = int(row_index) if 0 <= row_index < len(data): del data[row_index] with open(data_file, "w") as file: json.dump(data, file) return "記錄刪除成功", update_activity_display() else: return "錯誤: 行號超出範圍", update_activity_display() except ValueError: return "錯誤: 請輸入有效的數字行號", update_activity_display() # 主界面 def main_interface(): init_data_file() custom_css = """ .custom-btn { width: 100%; padding: 10px; margin: 5px 0; color: white; border: none; font-size: 16px; text-align: center; cursor: pointer; border-radius: 5px; } .btn-poop { background-color: #FF6347; } /* Tomato */ .btn-pee { background-color: #4682B4; } /* SteelBlue */ .btn-eat { background-color: #32CD32; } /* LimeGreen */ .btn-half { background-color: #FFD700; } /* Gold */ .btn-no-eat { background-color: #D3D3D3; } /* LightGray */ """ with gr.Blocks(css=custom_css) as app: gr.Markdown("## 🐾 狗狗活動記錄器") # 記錄活動按鈕 (不同顏色 + icon) with gr.Row(): poop_btn = gr.Button("💩 拉屎", elem_classes="custom-btn btn-poop") pee_btn = gr.Button("💦 尿尿", elem_classes="custom-btn btn-pee") eat_btn = gr.Button("🍽️ 全吃了", elem_classes="custom-btn btn-eat") half_eat_btn = gr.Button("🍛 吃了一半", elem_classes="custom-btn btn-half") no_eat_btn = gr.Button("🥄 沒怎麼吃", elem_classes="custom-btn btn-no-eat") # 活動記錄表格 gr.Markdown("### 📊 最近活動記錄 (僅顯示最近5條)") data_table = gr.Dataframe(update_activity_display(), interactive=False) # 顯示更多按鈕 show_more_btn = gr.Button("顯示更多記錄") show_less_btn = gr.Button("顯示最近5條", visible=False) # 刪除記錄功能 gr.Markdown("### 🗑️ 刪除記錄") row_to_delete = gr.Textbox(label="輸入要刪除的行號 (從 0 開始)") delete_btn = gr.Button("刪除記錄") delete_msg = gr.Textbox(label="刪除狀態", interactive=False) # 綁定活動按鈕邏輯 poop_btn.click(lambda: save_activity("拉屎"), outputs=[data_table]) pee_btn.click(lambda: save_activity("尿尿"), outputs=[data_table]) eat_btn.click(lambda: save_activity("全吃了"), outputs=[data_table]) half_eat_btn.click(lambda: save_activity("吃了一半"), outputs=[data_table]) no_eat_btn.click(lambda: save_activity("沒怎麼吃"), outputs=[data_table]) # 綁定顯示更多邏輯 show_more_btn.click( lambda: (update_activity_display(show_all=True), gr.update(visible=False), gr.update(visible=True)), inputs=[], outputs=[data_table, show_more_btn, show_less_btn] ) show_less_btn.click( lambda: (update_activity_display(show_all=False), gr.update(visible=True), gr.update(visible=False)), inputs=[], outputs=[data_table, show_more_btn, show_less_btn] ) # 刪除記錄邏輯 delete_btn.click( delete_activity, inputs=[row_to_delete], outputs=[delete_msg, data_table] ) return app # 啟動應用 main_interface().launch(share=True, server_name="0.0.0.0", server_port=7860)