h-1.flet.3/minimal.py

177 lines
5.3 KiB
Python

import flet as ft
import sqlite3
import signal
import sys
import logging
from datetime import datetime
def init_db():
conn = sqlite3.connect('sales.db')
cursor = conn.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS sales (
id INTEGER PRIMARY KEY AUTOINCREMENT,
customer TEXT NOT NULL,
product TEXT NOT NULL,
amount REAL NOT NULL,
date TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
''')
conn.commit()
conn.close()
return True
def load_sales():
conn = sqlite3.connect('sales.db')
cursor = conn.cursor()
cursor.execute('''
SELECT customer, product, amount, date
FROM sales
ORDER BY created_at DESC
LIMIT 20
''')
sales = cursor.fetchall()
conn.close()
return sales
def add_sale(customer, product, amount):
conn = sqlite3.connect('sales.db')
cursor = conn.cursor()
cursor.execute('''
INSERT INTO sales (customer, product, amount, date)
VALUES (?, ?, ?, ?)
''', (customer, product, float(amount), datetime.now().strftime("%Y-%m-%d")))
conn.commit()
conn.close()
return True
def cleanup_resources():
"""リソースをクリーンアップ"""
try:
logging.info("アプリケーション終了処理開始")
print("✅ 正常終了処理完了")
logging.info("アプリケーション正常終了")
except Exception as e:
logging.error(f"クリーンアップエラー: {e}")
print(f"❌ クリーンアップエラー: {e}")
def signal_handler(signum, frame):
"""シグナルハンドラ"""
print(f"\nシグナル {signum} を受信しました")
cleanup_resources()
sys.exit(0)
def main(page: ft.Page):
# ログ設定
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('app.log'),
logging.StreamHandler()
]
)
# シグナルハンドラ設定
signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)
logging.info("アプリケーション起動")
# データベース初期化
try:
init_db()
logging.info("データベース初期化完了")
except Exception as e:
logging.error(f"データベース初期化エラー: {e}")
print(f"❌ データベース初期化エラー: {e}")
page.title = "販売アシスト"
page.window_width = 400
page.window_height = 600
# ウィンドウクローズイベント
def on_window_close(e):
logging.info("ウィンドウクローズイベント")
cleanup_resources()
page.on_window_close = on_window_close
# UI要素定義
customer = ft.TextField(label="顧客名")
product = ft.TextField(label="商品名")
amount = ft.TextField(label="金額")
list_view = ft.Column()
def add_sale_clicked(e):
if customer.value and product.value and amount.value:
try:
# 保存前に値を取得
customer_val = customer.value
product_val = product.value
amount_val = amount.value
# データベースに保存
add_sale(customer_val, product_val, amount_val)
# フィールドをクリア
customer.value = ""
product.value = ""
amount.value = ""
# リスト更新
update_list()
# 成功メッセージ
page.snack_bar = ft.SnackBar(
content=ft.Text("保存しました"),
bgcolor=ft.Colors.GREEN
)
page.snack_bar.open = True
page.update()
logging.info(f"売上データ追加: {customer_val} {product_val} {amount_val}")
except Exception as ex:
logging.error(f"保存エラー: {ex}")
page.snack_bar = ft.SnackBar(
content=ft.Text("エラーが発生しました"),
bgcolor=ft.Colors.RED
)
page.snack_bar.open = True
page.update()
def update_list():
try:
list_view.controls.clear()
sales = load_sales()
for sale in sales:
customer, product, amount, date = sale
list_view.controls.append(
ft.Text(f"{date}: {customer} - {product}: ¥{amount:,.0f}")
)
except Exception as e:
logging.error(f"リスト更新エラー: {e}")
# ボタン定義(関数定義後)
add_btn = ft.Button("追加", on_click=add_sale_clicked)
# 初期データ読み込み
update_list()
logging.info("UI初期化完了")
print("🚀 アプリケーション起動完了")
page.add(
ft.Text("売上管理", size=20),
customer,
product,
amount,
add_btn,
ft.Divider(),
ft.Text("売上一覧", size=16),
list_view
)
if __name__ == "__main__":
ft.app(target=main)