h-1.flet.3/app_compiz_shortcuts.py

388 lines
16 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
Compiz対応ショートカットキー画面
Mate+Compiz環境で安定動作するUI
"""
import flet as ft
import signal
import sys
import logging
from datetime import datetime
class CompizShortcutsApp:
"""Compiz対応ショートカットキーアプリケーション"""
def __init__(self, page: ft.Page):
self.page = page
# ログ設定
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('app.log'),
logging.StreamHandler()
]
)
# シグナルハンドラ設定
def signal_handler(signum, frame):
print(f"\nシグナル {signum} を受信しました")
print("✅ 正常終了処理完了")
logging.info("アプリケーション正常終了")
sys.exit(0)
self.signal_handler = signal_handler # インスタンス変数として保存
signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)
# ウィンドウ設定
page.title = "Compiz対応ショートカットキー"
page.window_width = 800
page.window_height = 600
page.theme_mode = ft.ThemeMode.LIGHT
# ウィンドウクローズイベント
page.on_window_close = lambda _: signal_handler(0, None)
# メインコンテナ
self.main_container = ft.Column([], expand=True, spacing=20)
# ショートカットキー設定
self.setup_shortcuts()
# UI構築
self.build_ui()
logging.info("Compiz対応ショートカットキーアプリ起動完了")
print("🚀 Compiz対応ショートカットキーアプリ起動完了")
def setup_shortcuts(self):
"""ショートカットキー設定"""
self.key_pressed = {} # キー押下状態を管理
self.last_key_time = {} # 最後のキー押下時間を管理
def on_keyboard(e: ft.KeyboardEvent):
import time
current_time = time.time()
# キーリピート防止0.2秒以内の同じキーを無視)
if e.key in self.last_key_time and current_time - self.last_key_time[e.key] < 0.2:
return
self.last_key_time[e.key] = current_time
# 数字キーで機能呼び出し
if e.key == "1":
self.show_function("ダッシュボード", "統計情報の表示")
elif e.key == "2":
self.show_function("売上管理", "売上データの入力・管理")
elif e.key == "3":
self.show_function("顧客管理", "顧客マスタの編集")
elif e.key == "4":
self.show_function("商品管理", "商品マスタの編集")
elif e.key == "5":
self.show_function("伝票入力", "伝票データの入力")
elif e.key == "6":
self.show_function("テキストエディタ", "下書き・メモの作成")
elif e.key == "7":
self.show_function("GPS機能", "GPS情報の取得・管理")
elif e.key == "8":
self.show_function("PDF出力", "帳票のPDF出力")
elif e.key == "9":
self.show_function("設定", "アプリケーション設定")
elif e.key == "0":
self.show_function("終了", "アプリケーションの終了")
# ESCキーで終了
elif e.key == "Escape":
self.show_function("終了", "アプリケーションの終了")
# SPACEで実行
elif e.key == " ":
self.execute_current_function()
# ENTERで実行
elif e.key == "Enter":
self.execute_current_function()
self.page.on_keyboard_event = on_keyboard
logging.info("ショートカットキー設定完了")
def build_ui(self):
"""UIを構築"""
# タイトル
self.title = ft.Text(
"Compiz対応ショートカットキー",
size=36,
weight=ft.FontWeight.BOLD,
color=ft.Colors.BLUE_900,
text_align=ft.TextAlign.CENTER
)
# 説明テキスト
self.description = ft.Text(
"Mate+Compiz環境で安定動作するショートカットキー対応画面",
size=18,
color=ft.Colors.GREY_600,
text_align=ft.TextAlign.CENTER
)
# 現在の機能表示
self.current_function = ft.Container(
content=ft.Text(
"機能: 未選択",
size=24,
weight=ft.FontWeight.BOLD,
color=ft.Colors.WHITE,
text_align=ft.TextAlign.CENTER
),
padding=20,
bgcolor=ft.Colors.ORANGE,
border_radius=15,
margin=ft.Margin.symmetric(vertical=10)
)
# ショートカットキーガイド
self.shortcuts_guide = ft.Container(
content=ft.Column([
ft.Text("ショートカットキー一覧", size=20, weight=ft.FontWeight.BOLD, text_align=ft.TextAlign.CENTER),
ft.Divider(height=2, thickness=2),
self.create_shortcut_row("1", "ダッシュボード", "統計情報の表示", ft.Colors.BLUE),
self.create_shortcut_row("2", "売上管理", "売上データの入力・管理", ft.Colors.GREEN),
self.create_shortcut_row("3", "顧客管理", "顧客マスタの編集", ft.Colors.ORANGE),
self.create_shortcut_row("4", "商品管理", "階層構造商品マスター編集", ft.Colors.PURPLE),
self.create_shortcut_row("5", "伝票入力", "伝票データの入力", ft.Colors.RED),
self.create_shortcut_row("6", "テキストエディタ", "下書き・メモの作成", ft.Colors.TEAL),
self.create_shortcut_row("7", "GPS機能", "GPS情報の取得・管理", ft.Colors.CYAN),
self.create_shortcut_row("8", "PDF出力", "帳票のPDF出力", ft.Colors.BROWN),
self.create_shortcut_row("9", "設定", "アプリケーション設定", ft.Colors.GREY),
self.create_shortcut_row("0", "終了", "アプリケーションの終了", ft.Colors.RED),
ft.Divider(height=2, thickness=2),
ft.Container(
content=ft.Column([
ft.Text("操作方法:", size=16, weight=ft.FontWeight.BOLD),
ft.Text("• 数字キー: 機能を選択", size=14),
ft.Text("• SPACE/ENTER: 選択した機能を実行", size=14),
ft.Text("• ESC: アプリケーション終了", size=14),
ft.Text("• マウスクリックも可能", size=14),
], spacing=5),
padding=15,
bgcolor=ft.Colors.BLUE_50,
border_radius=10
)
], spacing=10),
padding=20,
bgcolor=ft.Colors.WHITE,
border_radius=15,
shadow=ft.BoxShadow(
spread_radius=1,
blur_radius=5,
color=ft.Colors.GREY_300,
offset=ft.Offset(0, 2)
),
margin=ft.Margin.only(bottom=20)
)
# 実行ボタン(マウス用)
self.execute_btn = ft.Container(
content=ft.Button(
"実行",
on_click=self.execute_current_function,
style=ft.ButtonStyle(
bgcolor=ft.Colors.GREEN,
color=ft.Colors.WHITE,
elevation=5,
shape=ft.RoundedRectangleBorder(radius=10),
padding=ft.Padding.symmetric(horizontal=30, vertical=15)
)
),
alignment=ft.alignment.Alignment(0, 0),
margin=ft.Margin.symmetric(vertical=10)
)
# 環境情報
self.env_info = ft.Container(
content=ft.Column([
ft.Text("環境情報", size=16, weight=ft.FontWeight.BOLD),
ft.Text(f"OS: Linux Mint + Compiz"),
ft.Text(f"デスクトップ環境: Mate"),
ft.Text(f"対応: Compiz特殊操作に最適化"),
ft.Text(f"作成日時: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"),
], spacing=5),
padding=15,
bgcolor=ft.Colors.BLUE_50,
border_radius=10,
shadow=ft.BoxShadow(
spread_radius=1,
blur_radius=3,
color=ft.Colors.GREY_200,
offset=ft.Offset(0, 1)
)
)
# メインコンテナに追加
self.main_container.controls = [
ft.Container(
content=self.title,
margin=ft.Margin.only(bottom=10)
),
ft.Container(
content=self.description,
margin=ft.Margin.only(bottom=20)
),
ft.Divider(height=1, thickness=1),
self.current_function,
ft.Row([
self.execute_btn,
self.env_info
], alignment=ft.MainAxisAlignment.SPACE_BETWEEN),
ft.Divider(height=1, thickness=1),
ft.Container(
content=self.shortcuts_guide,
expand=True
)
]
# ページに追加
self.page.add(
ft.Container(
content=self.main_container,
padding=20,
bgcolor=ft.Colors.GREY_100,
expand=True
)
)
def create_shortcut_row(self, key: str, title: str, description: str, color: ft.Colors) -> ft.Container:
"""ショートカットキー行を作成"""
return ft.Container(
content=ft.Row([
ft.Container(
content=ft.Text(key, size=22, weight=ft.FontWeight.BOLD, color=ft.Colors.WHITE),
width=60,
height=60,
bgcolor=color,
alignment=ft.alignment.Alignment(0, 0),
border_radius=12,
shadow=ft.BoxShadow(
spread_radius=1,
blur_radius=3,
color=ft.Colors.with_opacity(0.3, color),
offset=ft.Offset(0, 2)
)
),
ft.Container(
content=ft.Column([
ft.Text(title, size=18, weight=ft.FontWeight.BOLD, color=ft.Colors.BLUE_900),
ft.Text(description, size=14, color=ft.Colors.GREY_600)
], spacing=3),
width=350,
padding=ft.Padding.symmetric(horizontal=15, vertical=10),
bgcolor=ft.Colors.GREY_50,
border_radius=10,
margin=ft.Margin.only(left=10)
)
], spacing=0),
margin=ft.Margin.only(bottom=10),
on_click=lambda _: self.show_function(title, description)
)
def show_function(self, title: str, description: str):
"""機能情報を表示"""
self.current_function.content.value = f"機能: {title}"
self.current_function.content.color = ft.Colors.WHITE
self.current_function.bgcolor = ft.Colors.BLUE_900
self.page.update()
logging.info(f"機能選択: {title}")
def execute_current_function(self, e=None):
"""現在の機能を実行"""
current_text = self.current_function.content.value
if "ダッシュボード" in current_text:
self.show_message("ダッシュボード機能を起動します", ft.Colors.GREEN)
# 実際のアプリ起動
self.launch_app("app_compiz_fixed.py")
logging.info("ダッシュボード機能実行")
elif "売上管理" in current_text:
self.show_message("売上管理機能を起動します", ft.Colors.GREEN)
self.launch_app("app_simple_working.py")
logging.info("売上管理機能実行")
elif "顧客管理" in current_text:
self.show_message("顧客管理機能を起動します", ft.Colors.GREEN)
self.launch_app("app_master_management.py")
logging.info("顧客管理機能実行")
elif "商品管理" in current_text:
self.show_message("商品管理機能を起動します", ft.Colors.GREEN)
self.launch_app("app_hierarchical_product_master.py")
logging.info("商品管理機能実行")
elif "伝票入力" in current_text:
self.show_message("伝票入力機能を起動します", ft.Colors.GREEN)
self.launch_app("app_slip_framework_demo.py")
logging.info("伝票入力機能実行")
elif "テキストエディタ" in current_text:
self.show_message("テキストエディタ機能を起動します", ft.Colors.GREEN)
self.launch_app("app_text_editor.py")
logging.info("テキストエディタ機能実行")
elif "GPS機能" in current_text:
self.show_message("GPS機能を起動します", ft.Colors.GREEN)
self.launch_app("app_theme_master.py")
logging.info("GPS機能実行")
elif "PDF出力" in current_text:
self.show_message("PDF出力機能を起動します", ft.Colors.GREEN)
self.launch_app("app_framework_demo.py")
logging.info("PDF出力機能実行")
elif "設定" in current_text:
self.show_message("設定機能を起動します", ft.Colors.GREEN)
self.launch_app("app_robust.py")
logging.info("設定機能実行")
elif "終了" in current_text:
self.show_message("アプリケーションを終了します", ft.Colors.RED)
self.signal_handler(0, None)
def launch_app(self, app_name: str):
"""アプリを起動"""
import subprocess
import os
try:
# 現在のディレクトリでアプリを起動
script_dir = os.path.dirname(os.path.abspath(__file__))
app_path = os.path.join(script_dir, app_name)
# バックグラウンドでアプリ起動
subprocess.Popen([
"flet", "run", app_path
], cwd=script_dir)
except Exception as e:
logging.error(f"アプリ起動エラー: {e}")
self.show_message(f"アプリ起動に失敗しました: {e}", ft.Colors.RED)
def show_message(self, message: str, color: ft.Colors):
"""メッセージを表示"""
self.page.snack_bar = ft.SnackBar(
content=ft.Text(message),
bgcolor=color
)
self.page.snack_bar.open = True
self.page.update()
def main(page: ft.Page):
"""メイン関数"""
try:
app = CompizShortcutsApp(page)
except Exception as e:
logging.error(f"アプリケーション起動エラー: {e}")
if __name__ == "__main__":
ft.run(main)