Python

【Python】UIボタンにドラッグ&ドロップ機能をつける

shamimatsu

ファイルをドロップする場所によって処理をわけたい時があり作成していましたが、ソースが複雑で久しぶりに見たらわからなくなっていたのでシンプルな機能だけ実装しテンプレートとして書き直しました。
ボタンにドロップするという内容はどこにも出てこなくてかなり苦労したことは覚えています。どこのサイトを参考にしたかは忘れてしまいましたが海外の記事だったと思います。
もしかすると今ならもっと良い方法があるのかもしれません。

UIボタンにドラッグ&ドロップ

使用ツール

PyCharmの無料版を使って作成しています。
PyCharm Community Edition 2020.3.4 x64

スクリプトの説明

python3.7を使用
PyQt5モジュールをインストールしてください。
コードをコピー&ペーストして実行するとウィンドウが立ち上がります。

テンプレートとはいえ何か機能を付けておいた方がわかりやすいため、
ドロップしたファイル名をダイアログに出す
ドロップしたデータがファイルかフォルダかを判断する機能を実装。

コード

ボタンを増やしたい場合はボタンのclassを丸ごとコピー&ペーストしてください。
コピー後の関数名の変更も忘れずに。

コードを元に改造する場合は以下の箇所を変更してください

# 文字やボタンはこちら
# レイアウト作成
# dropEventにコマンドを書く

from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt5.QtWidgets import QLabel, QPushButton, QGridLayout
import sys, os

class DragAndDrop(QtWidgets.QLabel):
    def __init__(self):
        super(DragAndDrop, self).__init__()
        self.setWindowTitle('Button Drop Template')
        self.setAlignment(QtCore.Qt.AlignCenter)
        self.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        self.setWindowFlags(QtCore.Qt.Window | QtCore.Qt.WindowCloseButtonHint)
        self.setAcceptDrops(True)

        # 文字やボタンはこちら
        self.Label1 = QLabel('ボタンにファイルをドロップしてください', self)
        self.Label1.setFont(QtGui.QFont('Meiryo', 10))

        self.button1 = CustomButtom1(u'ファイル名出力', self)
        self.button1.setFont(QtGui.QFont('Meiryo', 14))
        self.button1.setStyleSheet('QPushButton{ background-color: #0099ff; color: white ;}')

        self.button2 = CustomButtom2(u'ファイル・フォルダ判定', self)
        self.button2.setFont(QtGui.QFont('Meiryo', 14))
        self.button2.setStyleSheet('QPushButton{ background-color: #6666ff; color: white ;}')

        # レイアウト作成
        layout = QGridLayout()
        layout.addWidget(self.Label1)
        layout.addWidget(self.button1)
        layout.addWidget(self.button2)
        self.setLayout(layout)


class CustomButtom1(QPushButton):
    def __init__(self, title, parent):
        super(CustomButtom1, self).__init__(title, parent)
        self.setAcceptDrops(True)

    def dragEnterEvent(self, event):
        if event.mimeData().hasUrls():
            event.accept()
        else:
            event.ignore()

    # dropEventにコマンドを書く
    def dropEvent(self, event):
        mimedata = event.mimeData()
        urllist = mimedata.urls()
        for i in urllist:
            filepath = i.path()[1:].replace('/', '\\')
            filename = os.path.basename(filepath)
            QtWidgets.QMessageBox.information(self, 'タイトル', filename)


class CustomButtom2(QPushButton):
    def __init__(self, title, parent):
        super(CustomButtom2, self).__init__(title, parent)
        self.setAcceptDrops(True)

    def dragEnterEvent(self, event):
        if event.mimeData().hasUrls():
            event.accept()
        else:
            event.ignore()

    # dropEventにコマンドを書く
    def dropEvent(self, event):
        mimedata = event.mimeData()
        urllist = mimedata.urls()
        for i in urllist:
            filepath = i.path()[1:].replace('/', '\\')
            if os.path.isfile(filepath):
                QtWidgets.QMessageBox.information(self, 'タイトル', 'ファイルです')
            elif os.path.isdir(filepath):
                QtWidgets.QMessageBox.information(self, 'タイトル', 'フォルダです')


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    w = DragAndDrop()
    w.show()
    sys.exit(app.exec_())
ABOUT ME
shamimatsu
shamimatsu
3DCGデザイナー
ながらくゲーム業界で2D、3DCGデザイナーとして働いてきましたが、新しい業界に挑戦中です。 ブログのデザインをリニューアル中のため、見づらい箇所もあるかもしれませんが少しづつ修正していきます。
記事URLをコピーしました