ツールを作りながら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でカスタムウィジットを扱う