【Python】tkinter:テキストファイルをドラッグ&ドロップして内容を表示する

■実装の概要

tkinterの画面にテキストファイルをドラッグ&ドロップし、ファイルの中身を表示できるようにする。

・実装のイメージ図

▼前提条件

実装を行うにあたり、前提条件を以下に示す。

  • 画面サイズは600×600をデフォルトとする。
  • 画面サイズの固定はしない。
  • 連続してテキストファイルをドラッグ&ドロップする場合、前のデータは破棄する(一度、テキストボックスの内容を初期化する)。
  • 保存機能は所持しない。
  • バイナリデータファイル(例:Excelなど)をドラッグ&ドロップした場合は、テキストボックスに例外エラーを表示する。

■サンプルコード

import tkinter as tk
from tkinterdnd2 import DND_FILES, TkinterDnD

TITLE_NAME = 'ファイル ドラック&ドロップ'

# メイン画面クラス
class MainFrame(TkinterDnD.Tk):
    # コンストラクタ
    def __init__(self):
        
        #親クラス:TkinterDnD.Tkのコンストラクタ呼び出し
        super().__init__()
        
        # 画面サイズ
        frame_width = 600
        frame_height = 600
        self.geometry(f'{frame_width}x{frame_height}')
        
        # 画面サイズ固定したい場合
        # self.minsize(frame_width, frame_height)
        # self.maxsize(frame_width, frame_height)
        
        # タイトル
        self.title(f'{TITLE_NAME}')
        
        # フレーム(クラスのインスタンス)
        self.frame_drag_drop = frameDragDrop(self)
        
        # 配置(上下左右全表示)
        self.frame_drag_drop.grid(
            column=0
            , row=0
            , padx=5
            , pady=5
            , sticky=(tk.E, tk.W, tk.S, tk.N) 
        )
        
        # 画面サイズに合わせてフレームの大きさも伸縮
        self.columnconfigure(0, weight=1)
        self.rowconfigure(0, weight=1)

# ラベルクラス
class frameDragDrop(tk.LabelFrame):
    # コンストラクタ
    def __init__(self, parent):
        # 継承元も初期化
        super().__init__(parent)
        
        # テキストボックスを無効化でセット(折り返しなし)
        self.textbox = tk.Text(self, wrap=tk.NONE)
        self.textbox.insert(0.0, "Drag & Drop Here!!")
        self.textbox.configure(state='disabled')
                
        # ドラッグ&ドロップ
        self.textbox.drop_target_register(DND_FILES)
        self.textbox.dnd_bind('<<Drop>>', self.funcDragAndDrop)
        
        # スクロールバー設定(縦)
        self.yscrollbar = tk.Scrollbar(
            self
            , orient=tk.VERTICAL
            , command=self.textbox.yview
        )
        self.textbox['yscrollcommand'] = self.yscrollbar.set
        
        # スクロールバー設定(横)
        self.xscrollbar = tk.Scrollbar(
            self
            , orient=tk.HORIZONTAL
            , command=self.textbox.xview
        )
        self.textbox['xscrollcommand'] = self.xscrollbar.set


        # 配置
        self.textbox.grid(
            column=0
            , row=0
            , sticky=(tk.E, tk.W, tk.S, tk.N)
        )
        self.yscrollbar.grid(column=1, row=0, sticky=(tk.S, tk.N))
        self.xscrollbar.grid(column=0, row=1, sticky=(tk.E, tk.W))
        self.columnconfigure(0, weight=1)
        self.rowconfigure(0, weight=1)
    
    # ドラッグ&ドロップした時の処理
    def funcDragAndDrop(self, event):
        try:
            # テキストボックスのエリアを有効化し初期化
            self.textbox.configure(state='normal')
            self.textbox.delete(0.0, tk.END)
            
            # ファイルオープン
            with open(event.data) as f:
                # 1行ずつ読み込み
                for line in f:
                    # 1行の文字を取得
                    line = line.strip()
                    # テキストボックスに出力(改行コード:\n)
                    self.textbox.insert(tk.END, f"{line}\n")

        # 例外処理
        except Exception as e:
            self.textbox.insert(tk.END,f"エラー:{e}")
        

# メイン処理
if __name__ == '__main__':
    app = MainFrame()
    app.mainloop()
   

■実行結果

・実行初期画面


・テキストファイルをドラッグ&ドロップ

複数行「hoge」列挙したテキストファイル


・Excelファイルをドラッグ&ドロップした場合

■参考

実装するにあたり、参考とさせていただいたURLを以下に記載する。

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