简体   繁体   中英

PyQt5 - Drag and Drop in QDialog

I have a main pyqt5 application.

On click of a button i would like to call a QDialog and on submit of QDialog want to capture the result of QDialog in main application.

Below is a pyqt module which i like add it to QDialog, is this possible, and want to capture the result as well in main application ?

I don't know where to start.

import sys
from PyQt5.QtCore import QSize
from PyQt5 import QtWidgets, QtCore,QtGui
from PyQt5.QtGui import QColor, QDrag, QPainter, QPixmap
from PyQt5.QtWidgets import QApplication
from PyQt5 import QtCore, QtWidgets
from win32api import GetSystemMetrics
from PyQt5.QtGui import QImage, QPalette, QBrush

w=GetSystemMetrics(0)/1366
h=GetSystemMetrics(1)/768

class Button(QtWidgets.QPushButton):
    def mouseMoveEvent(self, e):
        if e.buttons() != QtCore.Qt.LeftButton:
            return

        # write the relative cursor position to mime data
        mimeData = QtCore.QMimeData()
        # simple string with 'x,y'
        mimeData.setText('%d,%d' % (e.x(), e.y()))

        pixmap = QtWidgets.QWidget.grab(self)

        # below makes the pixmap half transparent
        painter = QtGui.QPainter(pixmap)
        painter.setCompositionMode(painter.CompositionMode_DestinationIn)
        painter.fillRect(pixmap.rect(), QtGui.QColor(0, 0, 0, 127))
        painter.end()

        # make a QDrag
        drag = QtGui.QDrag(self)
        # put our MimeData
        drag.setMimeData(mimeData)
        # set its Pixmap
        drag.setPixmap(pixmap)
        # shift the Pixmap so that it coincides with the cursor position
        drag.setHotSpot(e.pos())

        # start the drag operation
        # exec_ will return the accepted action from dropEvent
        if drag.exec_(QtCore.Qt.CopyAction | QtCore.Qt.MoveAction) == QtCore.Qt.MoveAction:
            print('moved')
        else:
            print('copied')

class Example(QtWidgets.QWidget):
    def __init__(self):
        super(Example, self).__init__()
        self.initUI()

    def initUI(self):
        self.setAcceptDrops(True)

        button = Button('Draggable Text', self)
        button.setStyleSheet("font-size: 15px;background-color: rgb(255,255,255); margin:5px; border:1px solid rgb(255, 255, 255); ")
        button.move(100, 65)
        self.buttons = [button]
        self.setWindowTitle('Copy or Move')
        self.setFixedSize(960, 515)

        oImage = QImage(r"C:\Users\vaas\Desktop\background.jpg")
        sImage = oImage.scaled(QSize(960*w/1,515*h/1))                   # resize Image to widgets size
        palette = QPalette()
        palette.setBrush(QPalette.ColorRole(10), QBrush(sImage))                     # 10 = Windowrole
        self.setPalette(palette)

    def dragEnterEvent(self, e):
        e.accept()

    def dropEvent(self, e):
        # get the relative position from the mime data
        mime = e.mimeData().text()
        x, y = map(int, mime.split(','))

        if e.keyboardModifiers() & QtCore.Qt.ShiftModifier:
            # copy
            # so create a new button
            button = Button('Button', self)
            # move it to the position adjusted with the cursor position at drag
            button.move(e.pos()-QtCore.QPoint(x, y))
            # show it
            button.show()
            # store it
            self.buttons.append(button)
            # set the drop action as Copy
            e.setDropAction(QtCore.Qt.CopyAction)
        else:
            # move
            # so move the dragged button (i.e. event.source())
            print('mine°',e.pos())
            e.source().move(e.pos()-QtCore.QPoint(x, y))
            # set the drop action as Move
            e.setDropAction(QtCore.Qt.MoveAction)
        # tell the QDrag we accepted it
        e.accept()

def main():
    app = QApplication(sys.argv)
    ex = Example()
    ex.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

Start with http://doc.qt.io/qt-5/dnd.html

Play with the example below:

import sys
from PyQt5           import QtWidgets, QtCore, QtGui
from PyQt5.QtCore    import QSize
from PyQt5.QtGui     import (QColor, QDrag, QPainter, QPixmap, 
                             QImage, QPalette, QBrush)
from PyQt5.QtWidgets import QApplication, QHBoxLayout, QVBoxLayout
from win32api import GetSystemMetrics


w=GetSystemMetrics(0)/1366
h=GetSystemMetrics(1)/768

### +++++++++++++++++++++++++++++
class Window2(QtWidgets.QWidget):

    def __init__(self):
        super().__init__()
        # To be able to receive media dropped on a widget, call setAcceptDrops(true) 
        # for the widget, and reimplement the dragEnterEvent() and 
        # dropEvent() event handler functions.
        self.setAcceptDrops(True)

        self.setGeometry(QtCore.QRect(20, 50, 180, 600))
        self.lay = QVBoxLayout()
        self.lay.addWidget(QtWidgets.QPushButton('Button1'))
        self.lay.addWidget(QtWidgets.QPushButton('Button2'))
        self.lay.addWidget(QtWidgets.QPushButton('Button3'))
        palette = self.palette()
        palette.setColor(QPalette.Window, QColor('blue'))
        self.setPalette(palette)
        self.setLayout(self.lay)
        self.textLabel = ''

    # The dragEnterEvent() function is typically used to inform Qt about the types 
    # of data that the widget accepts. You must reimplement this function 
    # if you want to receive either QDragMoveEvent or QDropEvent 
    # in your reimplementations of dragMoveEvent() and dropEvent().
    def dragEnterEvent(self, e):
        e.accept()

    # The dropEvent() is used to unpack dropped data and 
    # handle it in way that is suitable for your application.
    def dropEvent(self, e):
        #self.textLabel = 'Drag and Drop. QLabel. e.mimeData().text() -> `{}`'.format(e.mimeData().text())
        self.lay.addWidget(QtWidgets.QLabel('Drag and Drop. QLabel. e.mimeData().text() -> `{}`'\
                                            .format(e.mimeData().text())))
        e.accept()


class Button(QtWidgets.QPushButton):
    def mouseMoveEvent(self, e):
        if e.buttons() != QtCore.Qt.LeftButton:
            return

        # write the relative cursor position to mime data
        mimeData = QtCore.QMimeData()
        # simple string with 'x,y'
        mimeData.setText('%d,%d' % (e.x(), e.y()))

        pixmap = QtWidgets.QWidget.grab(self)

        # below makes the pixmap half transparent
        painter = QtGui.QPainter(pixmap)
        painter.setCompositionMode(painter.CompositionMode_DestinationIn)
        painter.fillRect(pixmap.rect(), QtGui.QColor(0, 0, 0, 127))
        painter.end()

        # make a QDrag
        drag = QtGui.QDrag(self)
        # put our MimeData
        drag.setMimeData(mimeData)
        # set its Pixmap
        drag.setPixmap(pixmap)
        # shift the Pixmap so that it coincides with the cursor position
        drag.setHotSpot(e.pos())

        # start the drag operation
        # exec_ will return the accepted action from dropEvent
        if drag.exec_(QtCore.Qt.CopyAction | QtCore.Qt.MoveAction) == QtCore.Qt.MoveAction:
            print('moved')
        else:
            print('copied')

class Example(QtWidgets.QWidget):
    def __init__(self):
        super(Example, self).__init__()

        self.w2 = Window2()                 # +++
        self.w2.show()                      # +++        

        self.initUI()

    def initUI(self):
        self.setAcceptDrops(True)

        button = Button('Draggable Text', self)
        button.setStyleSheet("font-size: 15px;background-color: rgb(255,255,255); margin:5px; border:1px solid rgb(255, 255, 255); ")
        button.move(100, 65)
        self.buttons = [button]
        self.setWindowTitle('Copy or Move')
        self.setFixedSize(960, 515)

        oImage = QImage(r"C:\Users\vaas\Desktop\background.jpg")
        #oImage = QImage(r"logo.png")
        sImage = oImage.scaled(QSize(960*w/1,515*h/1))              # resize Image to widgets size
        palette = QPalette()
        palette.setBrush(QPalette.ColorRole(10), QBrush(sImage))    # 10 = Windowrole
        self.setPalette(palette)

    def dragEnterEvent(self, e):
        e.accept()

    def dropEvent(self, e):
        # get the relative position from the mime data
        mime = e.mimeData().text()
        x, y = map(int, mime.split(','))

        if e.keyboardModifiers() & QtCore.Qt.ShiftModifier:
            # copy
            # so create a new button
            button = Button('Button', self)
            # move it to the position adjusted with the cursor position at drag
            button.move(e.pos()-QtCore.QPoint(x, y))
            # show it
            button.show()
            # store it
            self.buttons.append(button)
            # set the drop action as Copy
            e.setDropAction(QtCore.Qt.CopyAction)
        else:
            # move
            # so move the dragged button (i.e. event.source())
            print('mine°',e.pos())
            e.source().move(e.pos()-QtCore.QPoint(x, y))
            # set the drop action as Move
            e.setDropAction(QtCore.Qt.MoveAction)
        # tell the QDrag we accepted it
        e.accept()

def main():
    app = QApplication(sys.argv)
    ex = Example()
    ex.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM