QMimeDataにファイルのデータをセットしてみる
2022/02/09 categories:Python| tags:Python|QMimeData|PyQt5|
PyQt5のQMimeDataにファイルのデータをセットするプログラムを作ってみました。
処理内容
QMimeDataにPNGファイルをセットする場合は、以下のようなコードです。
def load_file(self, filename):
stream = QtCore.QFile(filename)
stream.open(QtCore.QFile.ReadOnly)
data = stream.readAll()
stream.close()
return data
mime_data = QtCore.QMimeData()
mime_data.setData( 'image/png', self.load_file('test01.png') )
mime_data.setUrls([ QtCore.QUrl().fromLocalFile('test01.png') ])
QtCore.QMimeData().setData()にmimeタイプとデータのQByteArrayを渡して、setUrls()でファイルのパスをQUrlとして渡すとデータをセットできます。ファイルのデータをQByteArrayに変換するには、QFile()のreadAll()を使うとよいようです。
QMimeDataからセットしたデータを取得できるか確認するために、QDropEventを使用してデータを取得するプログラムを作成して確認しました。
実行結果
ボタンをクリックするとローカルにあるファイルをQMimeDataにセットしてからdropEventを実行して、dropEventの処理内でwidgetへデータを表示しています。
Pythonコード
import sys
from pathlib import Path
from PyQt5 import QtWidgets, QtCore, QtGui
class Widget(QtWidgets.QWidget):
def __init__(self):
super(Widget, self).__init__()
self.resize(620, 500)
self.setWindowTitle('QMimeData test')
self.view0, self.view1 = QtWidgets.QGraphicsView(), QtWidgets.QGraphicsView()
self.text0, self.text1 = QtWidgets.QTextEdit(), QtWidgets.QTextEdit()
self.button0, self.button1 = QtWidgets.QPushButton('Drop test image'), QtWidgets.QPushButton('Drop test text')
self.setLayout( QtWidgets.QGridLayout(self) )
self.layout().setContentsMargins(0, 0, 0, 0)
self.layout().addWidget(self.button0, 0, 0, 1, 1)
self.layout().addWidget(self.button1, 0, 1, 1, 1)
self.layout().addWidget(self.view0, 1, 0, 1, 1)
self.layout().addWidget(self.text0, 1, 1, 1, 1)
self.layout().addWidget(self.view1, 2, 0, 1, 1)
self.layout().addWidget(self.text1, 2, 1, 1, 1)
self.view0.setScene( QtWidgets.QGraphicsScene() )
self.view1.setScene( QtWidgets.QGraphicsScene() )
self.button0.clicked.connect(self.drop_test0)
self.button1.clicked.connect(self.drop_test1)
def load_file(self, filename):
stream = QtCore.QFile(filename)
stream.open(QtCore.QFile.ReadOnly)
data = stream.readAll()
stream.close()
return data
def drop_test0(self):
self.view0.scene().clear(), self.view1.scene().clear(), self.text0.clear(), self.text1.clear()
mime_data = QtCore.QMimeData()
mime_data.setData( 'image/png', self.load_file('test01.png') )
mime_data.setData( 'image/jpeg', self.load_file('test02.jpg') )
mime_data.setUrls([ QtCore.QUrl().fromLocalFile('test01.png'), QtCore.QUrl().fromLocalFile('test02.jpg') ])
drop_event = QtGui.QDropEvent(
QtCore.QPointF(0.0, 0.0), QtCore.Qt.DropAction.MoveAction,
mime_data, QtCore.Qt.MouseButton.LeftButton, QtCore.Qt.KeyboardModifier.NoModifier
)
self.dropEvent(drop_event)
def drop_test1(self):
self.view0.scene().clear(), self.view1.scene().clear(), self.text0.clear(), self.text1.clear()
mime_data = QtCore.QMimeData()
mime_data.setData('text/plain', self.load_file('test01.txt') )
mime_data.setData('text/plain', self.load_file('test02.txt') )
mime_data.setUrls([ QtCore.QUrl().fromLocalFile('test01.txt'), QtCore.QUrl().fromLocalFile('test02.txt') ])
drop_event = QtGui.QDropEvent(
QtCore.QPointF(0.0, 0.0), QtCore.Qt.DropAction.MoveAction,
mime_data, QtCore.Qt.MouseButton.LeftButton, QtCore.Qt.KeyboardModifier.NoModifier
)
self.dropEvent(drop_event)
def dropEvent(self, event: QtGui.QDropEvent) -> None:
if event.mimeData().hasUrls():
paths = [ url.toLocalFile() for url in event.mimeData().urls() ]
if '.png' in [ Path(p).suffix for p in paths ]:
self.view0.scene().addPixmap( QtGui.QPixmap(paths[0]) )
self.view1.scene().addPixmap( QtGui.QPixmap(paths[1]) )
else:
with open(paths[0], mode='r') as f:
self.text0.setText( f.read() )
with open(paths[1], mode='r') as f:
self.text1.setText( f.read() )
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
widget = Widget()
widget.show()
app.exec()