2
1

Tkinterを使用したファイルオープナーアプリの作成

Last updated at Posted at 2024-03-03

はじめに

この記事では、Tkinterを使用してシンプルなファイルオープナーアプリを作成する方法を紹介します。アプリでは、ファイルの登録や閲覧が簡単に行えるように設計されています。以下に、コードとその説明を示します。

2024-03-04 (1).png
2024-03-04 (3).png

file_opener.py
import tkinter as tk
from tkinter import filedialog
from tkinter import ttk
import json
import subprocess
import os

class App:
    def __init__(self, root):
        self.root = root
        self.root.title("File Opener")
        # ウィンドウの大きさを設定
        self.root.geometry("500x230")
        # ウィンドウ全体にNotebookを広げる
        self.root.rowconfigure(0, weight=1)
        self.root.columnconfigure(0, weight=1)

        self.entries = []
        self.load_data()

        # ウィジェットの配置
        self.create_widgets()

        # ウィンドウが閉じられるときにデータを保存
        self.root.protocol("WM_DELETE_WINDOW", self.on_close)

    def create_widgets(self):
        # ノートブック
        self.notebook = ttk.Notebook(self.root)
        self.notebook.grid(row=0, column=0, columnspan=3, rowspan=5, padx=5, pady=5, sticky="nsew")

        # 登録するタブ
        register_tab = ttk.Frame(self.notebook)
        self.notebook.add(register_tab, text="登録する")

        # 表示名とファイルパスのエントリー
        label_name = tk.Label(register_tab, text="表示名:")
        label_name.grid(row=0, column=0, sticky=tk.W, padx=10, pady=5)

        label_path = tk.Label(register_tab, text="ファイルパス:")
        label_path.grid(row=1, column=0, sticky=tk.W, padx=10, pady=5)

        label_params1 = tk.Label(register_tab, text="パラメータ1:")
        label_params1.grid(row=2, column=0, sticky=tk.W, padx=10, pady=5)

        label_params2 = tk.Label(register_tab, text="パラメータ2:")
        label_params2.grid(row=3, column=0, sticky=tk.W, padx=10, pady=5)

        label_color = tk.Label(register_tab, text="ボタンの色:")
        label_color.grid(row=4, column=0, sticky=tk.W, padx=10, pady=5)

        self.entry_name = tk.Entry(register_tab)
        self.entry_name.grid(row=0, column=1, padx=10, pady=5, ipadx=100)

        self.entry_path = tk.Entry(register_tab)
        self.entry_path.grid(row=1, column=1, padx=10, pady=5, ipadx=100)

        # ファイル選択ボタン
        select_button = tk.Button(register_tab, text="選択", command=self.browse_file)
        select_button.grid(row=1, column=2, padx=5, pady=5)

        # ボタンの色選択
        colors = ["", "yellow", "green", "blue"]
        self.selected_color = tk.StringVar()
        color_dropdown = ttk.Combobox(register_tab, textvariable=self.selected_color, values=colors, state="readonly")
        color_dropdown.grid(row=4, column=1, padx=10, pady=5, ipadx=90)
        color_dropdown.set("")

        # パラメータ入力エントリー
        self.entry_params1 = tk.Entry(register_tab)
        self.entry_params1.grid(row=2, column=1, padx=10, pady=5, ipadx=100)

        self.entry_params2 = tk.Entry(register_tab)
        self.entry_params2.grid(row=3, column=1, padx=10, pady=5, ipadx=100)

        # 登録ボタン
        register_button = tk.Button(register_tab, text="登録", command=self.register_entry)
        register_button.grid(row=5, column=1, pady=5)

        # 登録済みのボタンを表示するタブ
        self.show_tab = ttk.Frame(self.notebook)

        # 登録済みのボタンを表示
        self.show_registered_entries()

    def browse_file(self):
        file_path = filedialog.askopenfilename()
        self.entry_path.delete(0, tk.END)
        self.entry_path.insert(0, file_path)

    def register_entry(self):
        name = self.entry_name.get()
        path = self.entry_path.get()
        color = self.selected_color.get() if self.selected_color.get() else None
        params1 = self.entry_params1.get()
        params2 = self.entry_params2.get()

        if name and path:
            entry = {"name": name, "path": path}

            if color is not None:
                entry["color"] = color

            if params1:
                entry["params1"] = params1

            if params2:
                entry["params2"] = params2

            self.entries.append(entry)
            self.save_data()
            self.reset_and_show_entries()

            # エントリーをクリア
            self.entry_name.delete(0, tk.END)
            self.entry_path.delete(0, tk.END)
            self.selected_color.set("")
            self.entry_params1.delete(0, tk.END)
            self.entry_params2.delete(0, tk.END)

    def reset_and_show_entries(self):
        # 以前に登録されたボタンとタブを削除(最初のタブはスキップ)
        for tab in self.notebook.tabs()[1:]:
            self.notebook.forget(tab)

        # 再度表示
        self.show_registered_entries()

    def show_registered_entries(self):
        # 登録済みのボタンを表示
    
        # entriesリスト内の各エントリーに対して処理
        for i, entry in enumerate(self.entries):
            # グリッドの行と列を計算して、ボタンを適切な位置に配置
            row = i % 5
            column = i // 5
    
            # 新しいタブが必要な場合、新しいタブを作成
            if i % 25 == 0:
                self.show_tab = ttk.Frame(self.notebook)
                # タブをノートブックに追加
                self.notebook.add(self.show_tab, text=f"ボタンリスト ({i // 25 + 1})")
    
            # ボタンの表示名を取得
            button_text = entry["name"]
    
            # ボタンを作成し、対応するエントリーのファイルを開くコマンドを設定
            button = tk.Button(self.show_tab, text=button_text, command=lambda e=entry: self.open_file(e), width=10, height=1)
            
            # ボタンをグリッド上に配置
            button.grid(row=row, column=column, padx=5, pady=5)
    
            # エントリーに色情報がある場合、ボタンの背景色を設定
            if "color" in entry:
                button.config(bg="light" + entry["color"])

    def open_file(self, entry):
        # エントリーからファイルパスとパラメータを取得
        file_path = entry["path"]
        params1 = entry.get("params1", "")
        params2 = entry.get("params2", "")
    
        # フォルダの場合はフォルダを開く、それ以外は外部プログラムでファイルを開く
        if os.path.isdir(file_path):
            os.startfile(file_path)
        else:
            # 外部プログラムを呼び出してファイルを開く
            subprocess.run(["start", " ", file_path, params1, params2], shell=True)

    def load_data(self):
        try:
            with open("entries.json", "r") as file:
                self.entries = json.load(file)
        except FileNotFoundError:
            self.entries = []

    def save_data(self):
        with open("entries.json", "w") as file:
            # データを保存する際にensure_ascii=Falseを指定
            json.dump(self.entries, file, indent=2, ensure_ascii=False)
            # json.dump(self.entries, file, indent=2)

    def on_close(self):
        # ウィンドウが閉じられるときにデータを保存
        self.save_data()
        self.root.destroy()

if __name__ == "__main__":
    root = tk.Tk()
    app = App(root)
    root.mainloop()

各メソッドや処理の詳細な説明は以下になります。

1. __init__: ウィンドウの初期設定やデータの読み込みを行います。
2. create_widgets: ウィジェットの配置やタブの作成を行います。
3. browse_file: ファイル選択ダイアログを表示して、選択されたファイルのパスをエントリーに設定します。
4. register_entry: エントリーの登録処理を行います。エントリーの情報を取得し、entriesリストに追加します。
5. reset_and_show_entries: 以前に登録されたボタンとタブを削除して再表示します。
6. show_registered_entries: 登録済みのボタンを表示します。
7. open_file: 登録されたエントリーに基づいてファイルを開く処理を行います。
8. load_data: 以前に保存されたデータを読み込みます。
9. save_data: 現在のエントリーリストをJSONファイルに保存します。
10. on_close: ウィンドウが閉じられるときにデータを保存してアプリを終了します。

これにより、Tkinterを使用したシンプルなファイルオープナーアプリが完成します。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1