python: エクスプローラー(Finder)からフォルダのパスを取得する

プログラミング
スポンサーリンク




こんにちは、おみです。

前回、条件に一致したファイルを別のフォルダにコピーするプログラムを作成しましたが、フォルダのパスをテキストボックスに直接入力して指定するため、利便性にかけます。

 

そこで、フォルダのパスをエクスプローラー(macであればFinder)から取得してできるように処理を変更したいと思います。

 

↓前回の記事はこちら

https://moimoiblog.com/gui-application/file_move_application/python-file-move-application/
スポンサーリンク

機能の詳細

「選択」ボタンを押すとフォルダを選択する画面が開かれます。

選択画面から任意のフォルダを選択し、「Choose」を投下すると、テキストボックスに選択したフォルダのパスが記述されます。

「Choose」ボタン投下後

 

ソースコード

ファイル選択画面の表示は、下記のソースで行えます。

# メソッドの実行時に、ファイル選択画面が表示される。される。
# 戻り値: ファイルのパス(文字型)
tkinter.filedialog.askdirectory()

 

例えば、変数input_pathに取得したパスをテキストボックスに設定したい場合は、下記のように記述します。

input_path = tkinter.filedialog.askdirectory()

 

使用例

実際に機能を追加した後のソースは、こちらです。

・Main.py

import tkinter as tk

from src.Model import Model
from src.View import View
from src.Controller import Controller


class Application(tk.Frame):
def __init__(self, root):
# スーパークラスのコンストラクタを呼び出し
super().__init__(root)

# モデルをインスタンス化
self.model = Model(root)

# ビューをインスタンス化
self.view = View(root, self.model)

# コントローラーをインスタンス化
self.controller = Controller(root, self.model, self.view)

# Viewにcommandを設定
self.view.btn_sender_path["command"] = self.controller.btn_sender_clicked
self.view.btn_destination_path["command"] = self.controller.btn_destination_clicked
self.view.btn_execute["command"] = self.controller.btn_execute_clicked

# 画面の設定
root.geometry(str(self.model.width) + "x" + str(self.model.height))
root.title(self.model.title)


# mainメソッド
def main():
# 画面を生成
root = tk.Tk()

# 画面の設定を行う
window = Application(root)

# 画面を表示する
window.mainloop()


if __name__ == "__main__":
main()

・Model.py

import configparser as c
import tkinter as tk
import tkinter.filedialog
import os
import re
import glob
import shutil


class Model(object):
    def __init__(self, root):
        # ---------------------------------
        # 初期設定
        # ---------------------------------
        # configファイルを読み込み
        self.config = c.ConfigParser()
        self.config.read("config.ini")

        self.title = self.config["DISPLAY_INFO"]["title"]
        self.width = self.config["DISPLAY_INFO"]["width"]
        self.height = self.config["DISPLAY_INFO"]["height"]

        # 画面パーツに入力した値を格納する変数を宣言
        self.ent_sender_text = tk.StringVar()
        self.ent_destination_text = tk.StringVar()
        self.ent_file_name_text = tk.StringVar()
        self.ent_extention_text = tk.StringVar()
        self.lbl_message_text = tk.StringVar()

        self.ent_sender_text
        self.ent_destination_text

    # ボタンクリック時起動メソッド
    def execute(self):
        # 入力値を変数に格納する
        sender_path = self.ent_sender_text.get()
        destination_path = self.ent_destination_text.get()
        file_name = self.ent_file_name_text.get()
        extention = self.ent_extention_text.get()

        # 指定されたフォルダが存在するかを確認する
        if not sender_path:
            self.lbl_message_text.set("送信元フォルダパスが入力されていません")
            return

        if not os.path.exists(sender_path):
            self.lbl_message_text.set("送信元フォルダが存在しません")
            return

        if not destination_path:
            self.lbl_message_text.set("宛先フォルダパスが入力されていません")
            return

        if not os.path.exists(destination_path):
            self.lbl_message_text.set("宛先フォルダが存在しません")
            return

        # 入力した値の形式を調整する
        # 送信元フォルダパス ... 末尾に\を付ける
        if not re.match('\\$', sender_path):
            sender_path = sender_path + "\\"

        # 宛先フォルダパス ... 末尾に\を付ける
        if not re.match("\\$", destination_path):
            destination_path = destination_path + "\\"

        # 拡張子 ... 先頭に.を付ける
        if not extention:
            extention = "*"

        if extention[0:1] != r".":
            extention = r"." + extention

        # ファイル名、拡張子のパターンを生成する
        ptn_file_name = re.compile(file_name)
        ptn_extention = re.compile(extention)

        # ファイル一覧を取得する
        # file_map
        # キー: ファイル名
        # 値  : ファイルパス
        file_dict = {}
        for path in glob.glob(sender_path + "\\*"):
            file_dict.setdefault(path.replace(sender_path, ""), path)

        for str in file_dict.keys():
            res_file_name = ptn_file_name.search(str)
            res_extention = ptn_extention.search(str)
            if res_file_name != None and res_extention != None:
                shutil.copy(sender_path + str, destination_path + str)

        self.lbl_message_text.set("処理が完了しました。")

    def select_sender_folder(self):
        # 送信元フォルダを設定する
        self.ent_sender_text.set(tkinter.filedialog.askdirectory())

    def select_destination_folder(self):
        # 宛先フォルダを設定する
        self.ent_destination_text.set(tkinter.filedialog.askdirectory())

・View.py

import tkinter as tk


class View(object):
def __init__(self, root, model):
self.root = root
self.model = model

# ---------------------------------
# 画面の部品を生成
# ---------------------------------
# 送信元フォルダパスラベル
self.lbl_sender_path= tk.Label(
root,
text="送信元フォルダ"
)

# 送信元フォルダパス入力欄
self.ent_sender_path = tk.Entry(
root,
textvariable=model.ent_sender_text,
width=50
)

# 送信元フォルダパス取得ボタン
self.btn_sender_path = tk.Button(
root,
text="選択"
)


# 宛先フォルダパスラベル
self.lbl_destination_path = tk.Label(
root,
text="宛先フォルダ"
)

# 宛先フォルダパス入力欄
self.ent_destination_path = tk.Entry(
root,
textvariable=model.ent_destination_text,
width=50
)

# 宛先フォルダパス取得ボタン
self.btn_destination_path = tk.Button(
root,
text="選択"
)

# 対象ファイル名ラベル
self.lbl_file_name = tk.Label(
root,
text="ファイル名"
)

# 対象ファイル名入力欄
self.ent_file_name = tk.Entry(
root,
textvariable=model.ent_file_name_text,
width=50
)
# 拡張子名ラベル
self.lbl_extention = tk.Label(
root,
text="拡張子名"
)

# 拡張子名入力欄
self.ent_extention = tk.Entry(
root,
textvariable=model.ent_extention_text,
width=50
)

# 実行ボタン
self.btn_execute = tk.Button(
root,
text="実行"
)

# 出力欄ラベル
self.lbl_message = tk.Label(
root,
textvariable=model.lbl_message_text
)

# ---------------------------------
# 画面の部品を配置
# ---------------------------------
self.lbl_sender_path.grid(row=0, column=0)
self.ent_sender_path.grid(row=0, column=1)
self.btn_sender_path.grid(row=0, column=2)
self.lbl_destination_path.grid(row=1, column=0)
self.ent_destination_path.grid(row=1, column=1)
self.btn_destination_path.grid(row=1, column=2)
self.lbl_file_name.grid(row=2, column=0)
self.ent_file_name.grid(row=2, column=1)
self.lbl_extention.grid(row=3, column=0)
self.ent_extention.grid(row=3, column=1)
self.btn_execute.grid(row=4, column=0)
self.lbl_message.grid(row=4, column=1)

・Controller.py

class Controller(object):
def __init__(self, root, model, view):
self.root = root
self.model = model
self.view = view

# 実行ボタンクリック時の処理を定義
def btn_execute_clicked(self):
# モデルのメソッドを呼び出し
self.model.execute()

# 送信元フォルダ選択ボタンクリック時の処理を定義
def btn_sender_clicked(self):
# モデルのメソッドを呼び出し
self.model.select_sender_folder()

# 宛先フォルダ選択ボタンクリック時の処理を定義
def btn_destination_clicked(self):
# モデルのメソッドを呼び出し
self.model.select_destination_folder()

・config.ini

[DISPLAY_INFO]
title = "ファイル抽出"
width = 610
height = 140

コメント

タイトルとURLをコピーしました