Search code examples
pythondrag-and-droppyqt5

Drag and drop functionality using qpageview in pyqt5


I am using qpageview (See here and here) in pyqt5 to create a document viewer which can view pdf, jpg, png, and, svg files as part of a bigger project. The code so far is as follows, which is just a window to open the pdf/jpg/png/svg file.

import sys
import os
import glob

from PyQt5.QtCore import QDir
from PyQt5.QtWidgets import (QMainWindow, QApplication, QMenu, QVBoxLayout,
    QWidget, QAction, QFileDialog)
from PyQt5.QtGui import (QIcon, QKeySequence)
import qpageview

class MainWindow(QMainWindow):
    
    """Main Window."""

    def __init__(self, *args, **kwargs):
        """Initializer."""

        super(MainWindow,self).__init__(*args, **kwargs)

        self.window_title = 'Document Viewer'
        self.setWindowTitle(self.window_title)
        self.resize(600,450)

        widget = QWidget()
        self.setCentralWidget(widget)

        self.layout = QVBoxLayout()
        widget.setLayout(self.layout)

        self._createImageViewer()
        self._createMenu()

    def _createImageViewer(self):

        self.viewer = qpageview.View()
        self.layout.addWidget(self.viewer)
        self.viewer.show()

        return

    def _createMenu(self):
        self.file_menu  = self.menuBar().addMenu("&File")

        # File submenu
        self.openFileAction = QAction(QIcon.fromTheme('document-open'), 
            '&Open', self, shortcut = QKeySequence.Open, 
            triggered = self.openFile)
        self.file_menu.addAction(self.openFileAction)

    def openFile(self):
        fileName, _ = QFileDialog().getOpenFileName(self,
            "Open Documents", QDir.currentPath(), 
            "PDF (*.pdf)" 
            + ";;" + "PNG (*.png)"
            + ";;" + "JPEG (*.jpg *.jpeg)"
            + ";;" + "SVG (*.svg)"
            )

        if fileName:

            ext = os.path.splitext(fileName)[1]

            if ext == '.pdf':
                self.viewer.loadPdf(fileName)

            elif ext == '.jpg' or ext == '.jpeg' or ext == '.png':
                self.viewer.loadImages(glob.glob(fileName))
                
            elif ext == '.svg':
                self.viewer.loadSvgs(glob.glob(fileName))
                
            self.viewer.setViewMode(qpageview.FitWidth)

if __name__ == '__main__':
    
    app = QApplication(sys.argv)
    win = MainWindow()
    win.show()
    sys.exit(app.exec_()) 

However, I also require drag and drop functionality where the image files (png/jpg) can be dragged from this application to another external application. I know how to do this using QLabel() and I know this kind of functionality is also available for qpageview using QDrag (See here). However, I am not an expert and do not know how to proceed. Any help will be appreciated.


Solution

  • Okay, I finally managed to drag a png image to another external application. So just after the openFile(self) function (see my original question), I added the following two functions and now it works. I also had to add from qpageview.export import ImageExporter at the top where I am importing modules.

        def mousePressEvent(self, event):
            if event.button() == Qt.LeftButton:
                self.drag_start_position = event.pos()
    
        def mouseMoveEvent(self, event):
            if not (event.buttons() & Qt.LeftButton):
                return
    
            if (event.pos() - self.drag_start_position).manhattanLength() < QApplication.startDragDistance():
                return
    
            page = self.viewer.currentPage()
            if page:
                exporter = ImageExporter(page)
                mimedata = exporter.mimeData()
                exporter.drag(self,mimedata)