FletでPC管理アプリを実装してみた

2024/10/15

Flet

PythonのフレームワークのひとつであるFletでPC管理アプリを実装してみたので作り方をまとめました。

環境構築

Dockerで開発環境を構築しました。
開発環境はこちらからダウンロードできます。

開発

main.pyの中身を書き換えます。

main.py
import flet as ft
import sqlite3

# PC管理アプリのクラス
class PCManagementApp:
    def __init__(self, page: ft.Page):
        self.page = page  # Fletのページを設定
        self.conn = sqlite3.connect('pcmanagement.db')  # SQLiteデータベースに接続
        self.create_table()  # データベースのテーブルを作成
        self.build_ui()  # ユーザーインターフェイスを構築
        self.load_pc()  # データベースからデータを読み込む
        self.page.on_close = self.on_close  # ページが閉じられる際の処理を設定

    # データベースのテーブルを作成
    def create_table(self):
        cursor = self.conn.cursor()
        cursor.execute(
            '''
            CREATE TABLE IF NOT EXISTS pcmanagement(
                id INTEGER PRIMARY KEY,
                name TEXT,
                hostname TEXT,
                password TEXT,
                status TEXT,
                user TEXT
            )
            '''
        )
        self.conn.commit()

    # ページが閉じられる際にデータベース接続を閉じる
    def on_close(self, e):
        self.conn.close()

    # ユーザーインターフェイスを構築
    def build_ui(self):
        self.page.title = "PC Management App"  # ページタイトルを設定
        self.page.scroll = ft.ScrollMode.ADAPTIVE  # スクロールモードを設定

        # タイトルテキスト
        self.title = ft.Text(
            value="PC管理アプリ",
            theme_style=ft.TextThemeStyle.HEADLINE_MEDIUM
        )

        # 各入力フィールド
        self.pc_name_input = ft.TextField(label="PC名")
        self.pc_hostname_input = ft.TextField(label="ホスト名")
        self.pc_password_input = ft.TextField(label="パスワード")
        self.pc_status_input = ft.TextField(label="状態")
        self.pc_user_input = ft.TextField(label="利用者")

        # 登録ボタン
        self.add_button = ft.ElevatedButton(
            text="登 録",
            on_click=self.add_pc
        )

        # 更新ボタン(初期は非表示)
        self.update_button = ft.ElevatedButton(
            text="更 新",
            on_click=self.update_pc,
            visible=False
        )

        # 入力フィールドとボタンの行
        self.input_field = ft.Row(
            [
                self.pc_name_input,
                self.pc_hostname_input,
                self.pc_password_input,
                self.pc_status_input,
                self.pc_user_input,
                self.update_button,
                self.add_button
            ],
            alignment=ft.MainAxisAlignment.CENTER
        )

        # データ表示用のテーブル
        self.datatable = ft.DataTable(
            bgcolor="#E7D0A9",
            border_radius=5,
            border=ft.border.all(2, "#E7D0A9"),
            vertical_lines=ft.BorderSide(3, "#DFE7A9"),
            heading_row_height=30,
            columns=[
                ft.DataColumn(self.settings("ID", 25)),
                ft.DataColumn(self.settings("PC名", 200)),
                ft.DataColumn(self.settings("ホスト名", 200), numeric=True),
                ft.DataColumn(self.settings("パスワード", 200), numeric=True),
                ft.DataColumn(self.settings("状態", 100), numeric=True),
                ft.DataColumn(self.settings("利用者", 100), numeric=True),
                ft.DataColumn(self.settings("編集", 50)),
                ft.DataColumn(self.settings("削除", 50)),
            ],
            rows=[]
        )

        # ページにUI要素を追加
        self.page.add(
            ft.Column(
                [self.title, self.input_field, self.datatable],
                horizontal_alignment=ft.CrossAxisAlignment.CENTER
            )
        )

    # テーブルの設定
    def settings(self, cell_title, width_px):
        return ft.Container(
            ft.Text(cell_title),
            width=width_px,
            alignment=ft.alignment.center
        )

    # データベースからデータを読み込み、テーブルに表示
    def load_pc(self):
        cursor = self.conn.cursor()
        cursor.execute('SELECT * FROM pcmanagement')
        rows_data = cursor.fetchall()

        self.datatable.rows.clear()

        for row in rows_data:
            self.datatable.rows.append(
                ft.DataRow(
                    cells=[
                        ft.DataCell(ft.Text(row[0])),  # ID
                        ft.DataCell(ft.Text(row[1])),  # PC名
                        ft.DataCell(ft.Text(row[2])),  # ホスト名
                        ft.DataCell(ft.Text(row[3])),  # パスワード
                        ft.DataCell(ft.Text(row[4])),  # 状態
                        ft.DataCell(ft.Text(row[5])),  # 利用者
                        ft.DataCell(
                            ft.IconButton(
                                icon=ft.icons.EDIT,
                                on_click=lambda e, id=row[0]: self.edit_pc(id)  # 編集ボタン
                            )
                        ),
                        ft.DataCell(
                            ft.IconButton(
                                icon=ft.icons.DELETE,
                                on_click=lambda e, id=row[0]: self.delete_pc(id)  # 削除ボタン
                            )
                        )
                    ]
                )
            )
        self.page.update()

    # データを追加
    def add_pc(self, e):
        name = self.pc_name_input.value
        hostname = self.pc_hostname_input.value
        password = self.pc_password_input.value
        status = self.pc_status_input.value
        user = self.pc_user_input.value

        cursor = self.conn.cursor()
        cursor.execute(
            '''
            INSERT INTO pcmanagement (name, hostname, password, status, user) VALUES (?, ?, ?, ?, ?)
            ''',
            (name, hostname, password, status, user)
        )
        self.conn.commit()
        self.load_pc()

        # 入力フィールドをリセット
        self.pc_name_input.value = ""
        self.pc_hostname_input.value = ""
        self.pc_password_input.value = ""
        self.pc_status_input.value = ""
        self.pc_user_input.value = ""
        self.page.update()

    # 編集モードを有効化
    def edit_pc(self, pc_id):
        cursor = self.conn.cursor()
        cursor.execute(
            '''
            SELECT * FROM pcmanagement WHERE id = ?
            ''',
            (pc_id,)
        )
        row = cursor.fetchone()
        if row:
            self.pc_name_input.value = row[1]
            self.pc_hostname_input.value = row[2]
            self.pc_password_input.value = row[3]
            self.pc_status_input.value = row[4]
            self.pc_user_input.value = row[5]
            self.update_button.visible = True
            self.add_button.visible = False
            self.update_button.data = pc_id
            self.page.update()

    # データを更新
    def update_pc(self, e):
        pc_id = self.update_button.data
        name = self.pc_name_input.value
        hostname = self.pc_hostname_input.value
        password = self.pc_password_input.value
        status = self.pc_status_input.value
        user = self.pc_user_input.value

        cursor = self.conn.cursor()
        cursor.execute(
            '''
            UPDATE pcmanagement SET name = ?, hostname = ?, password = ?, status = ?, user = ? WHERE id = ?
            ''',
            (name, hostname, password, status, user, pc_id)
        )
        self.conn.commit()
        self.load_pc()

        # 入力フィールドをリセット
        self.pc_name_input.value = ""
        self.pc_hostname_input.value = ""
        self.pc_password_input.value = ""
        self.pc_status_input.value = ""
        self.pc_user_input.value = ""
        self.update_button.visible = False
        self.add_button.visible = True
        self.page.update()

    # データを削除
    def delete_pc(self, pc_id):
        cursor = self.conn.cursor()
        cursor.execute(
            '''
            DELETE FROM pcmanagement WHERE id = ?
            ''',
            (pc_id,)
        )
        self.conn.commit()
        self.load_pc()

# メイン関数
def main(page: ft.Page):
    PCManagementApp(page)

ft.app(target=main)

実行

Dockerイメージをビルドします。

docker compose build --no-cache

コンテナを起動します。

docker compose up

コンテナに接続します。

docker exec -it app bash

PC管理アプリを起動します。

flet run --web ./src./main.py --port 8000

001.png

今回はここまでです。

Related Posts

Fletで簡単なアプリを実装してみた

Fletで簡単なアプリを実装してみた