WhiteAtelier Archives
Another side of life, Behind the real.
2019-09-11 21:42:00 - Category : PySide | プログラミング
QTableViewにD&Dをしたい
QWidgetから派生しているUI部品に対して、エクスプローラーなどからドラッグアンドドロップでファイルを投げ込みたいときに、イベントの取り方などをまとめました。

ツールを作りながらPySideを勉強しているほわいとです。今日は、エクスプローラーなどから、ファイルをつかんで、そのままQTableViewにドロップするときのやり方についてメモします。

D&Dの実装は、QWidgetを継承しているコンポーネントならQTableViewに限らず可能だと思います。

QTableViewを継承した独自のコンポーネントを作る

今回はDroppableTableViewとしました。

from PySide2 import QtCore, QtWidgets
class DroppableTableView(QtWidgets.QTableView):
    def __init__(self, parent=None):
        super(DroppableTableView, self).__init__(parent)
        self.setAcceptDrops(True)

    def dragEnterEvent(self, event):
        if event.mimeData().hasUrls():
            for url in event.mimeData().urls():
                print(url)
            print("dragEnterEvent and accept")
            event.acceptProposedAction()
        else:
            event.ignore()

    def dragMoveEvent(self, event):
        pass

    def dropEvent(self, event):
        event.accept()
        print("dropEvent")

ここで非常に重要なポイントとして、

  • コンストラクタでsetAcceptDrops(True)を呼ぶこと
  • dragEnterEvent, dragMoveEvent, dropEventを必ず実装すること

です。 特に今回ハマったのは、とくにいらないdragMoveEventだからって実装しないと、dropEventが呼ばれないということでした。dragEnterEventはきちんと呼ばれるのですが、dropEventが呼ばれない!となった場合は、dragMoveEventを実装すると良いかもしれません。

クリティカルにここに書いてありました。Drag and Drop, dropEvent not being called?

Qt Designerでのカスタムウィジット

さて、今回はこうしてDroppableTableViewというカスタムウィジットを作りました。しかし、UIに関しては、pythonにロードするときにQUiLoaderを使っているケースも多いと思います。私もそうです。 目的のQTableViewをDroppableQTableViewに変えるにはどうしたらええんじゃ、ということで、別記事にてこちらはまとめたいと思います。

Qt Designer, QUiLoaderでカスタムウィジットを扱う

参考にした場所