如何从Qtablewidget拖动图像并将其添加到场景?

时间:2019-08-12 12:14:51

标签: python pyqt pyqt5

我有一个QTablewidget,它的单元格中包含图像。我的目标是将图像从tablewidget拖放到场景中。

我尝试在Qtablewidgets中实现dragevents,但是它不起作用。我给出了示例代码。

from PyQt5.QtCore import (QByteArray,QDataStream, QIODevice,pyqtSlot, QMimeData, QPointF, QPoint, Qt, QRect,QTimer,QLineF, QEvent,QRectF)
from PyQt5.QtGui import QColor,QDrag, QPainter, QPixmap,QFont,QFontMetrics,QBrush, QLinearGradient, QIcon, QPen, QPainterPath, QTransform,QCursor,QMouseEvent,QClipboard
from PyQt5.QtWidgets import QApplication,QGraphicsTextItem,QGraphicsItemGroup, QSizePolicy,QShortcut, QScrollArea, QPushButton,QLineEdit, QMainWindow,QInputDialog, QGraphicsPathItem,QDialog, QVBoxLayout,QGraphicsItem,QStatusBar,QTextEdit, QAction,QMenu, qApp,QSplitter, QButtonGroup, QToolButton, QFrame, QHBoxLayout, QGraphicsView, QGraphicsItem, QGraphicsPixmapItem, QLabel, QGraphicsScene, QWidget
import table1 as table


class GraphicsSceneClass(QGraphicsScene):
    global selectedObjType
    def __init__(self, parent=None):
        super(GraphicsSceneClass, self).__init__(parent)
        self.gridOn = 0
        self.setSceneRect(0, 0, 1920, 1080)
        self.setItemIndexMethod(QGraphicsScene.NoIndex)
        self.setBackgroundBrush(QBrush(Qt.black))




class MainWindow(QMainWindow):
    global selectedObjType
    # global item
    def __init__(self,):
        super(MainWindow, self).__init__()
        # self.createActions()
        # self.createMenus()
        # self.createToolbars()

        self.scene = GraphicsSceneClass()
        MainWindow.obj = self.scene
        self.view = QGraphicsView(self.scene)
        # self.view.setDragMode(QGraphicsView.RubberBandDrag)
        self.view.setMouseTracking(True)
        self.view.setRenderHint(QPainter.HighQualityAntialiasing)
        self.widg = QWidget()
        self.horizontalLayout = QHBoxLayout()

        self.table=QWidget()
        self.table.setLayout( table.Drag1Window())
        self.horizontalLayout.addWidget(self.table)
        self.horizontalLayout.addWidget(self.view)


        self.widg.setMouseTracking(True)
        self.widget = QWidget()
        self.widget.setLayout(self.horizontalLayout)
        self.setCentralWidget(self.widget)

if __name__=="__main__":
    import sys
    app=QApplication(sys.argv)
    mainWindow = MainWindow()

    mainWindow.show()

    sys.exit(app.exec_())

另一个module-table1.py

class Drag1Window(QVBoxLayout):
    def __init__(self, parent=None):
        super(Drag1Window, self).__init__(parent)
        self.setSpacing(0)
        self.setContentsMargins(0, 0, 0, 0)
        self.setGeometry(QRect(0,0,0,0))
        self.layoutdimension = DragTableItem()
        self.layoutdimension.setMinimumSize(300,300)
        self.addWidget(self.layoutdimension)






class DragTableItem(QTableWidget):

    global selectedObjType
    global rows
    rows = []
    def __init__(self, parent=None):
        super(DragTableItem, self).__init__()
        self.setRowCount(20)
        self.setColumnCount(2)
        # self.MyTable = QTableWidget(2,2)
        # filename = "SIG.csv"
        self.dragEnabled()
        col = "FlipHor"
        newItem = QTableWidgetItem(col)

        self.setImage(0, 1, "symbol.png")

                # Track_Image = QLabel(self)
                # pixmap = QPixmap('Track.png')
                # Track_Image.setPixmap(pixmap)

    def setImage(self, row, col, imagePath):
        image = ImageWidget(imagePath, self)
        self.setCellWidget(row, col, image)

class ImageWidget(QWidget):
    def __init__(self, imagePath, parent):
        super(ImageWidget, self).__init__(parent)
        self.picture = QPixmap(imagePath)

    def paintEvent(self, event):
        painter1 = QPainter(self)
        painter1.drawPixmap(0, 0, self.picture)

有人可以帮我将图像拖放到单元格中吗?

1 个答案:

答案 0 :(得分:1)

要使小部件支持拖动,必须重写mousePressEvent()方法。

class ImageWidget(QWidget):
    # ...

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            drag = QDrag(self)
            mimeData = QMimeData()
            mimeData.setImageData(self.picture)
            drag.setMimeData(mimeData)
            drag.setPixmap(self.picture)
            drag.setHotSpot(event.pos())
            drag.exec_()

要支持拖放,除了启用acceptDrops标志之外,您还必须覆盖dragEnterEvent(),dragMoveEvent()和dropEvent()方法。

class GraphicsView(QGraphicsView):
    def __init__(self, parent=None):
        super(GraphicsView, self).__init__(parent)
        # ...
        self.setAcceptDrops(True)


    def dragMoveEvent(self, event):
        if event.mimeData().hasImage():
            event.acceptProposedAction()

    def dropEvent(self, event):
        if event.mimeData().hasImage():
            pixmap = event.mimeData().imageData()
            if self.scene() is not None:
                it = self.scene().addPixmap(pixmap)
                it.setPos(self.mapToScene(event.pos()))
            event.acceptProposedAction()

完整示例:

from PyQt5.QtCore import Qt, QMimeData
from PyQt5.QtGui import QBrush, QDrag, QPainter, QPixmap
from PyQt5.QtWidgets import (
    QApplication,
    QGraphicsScene,
    QGraphicsView,
    QHBoxLayout,
    QMainWindow,
    QTableWidget,
    QTableWidgetItem,
    QVBoxLayout,
    QWidget,
)


class GraphicsScene(QGraphicsScene):
    def __init__(self, parent=None):
        super(GraphicsScene, self).__init__(parent)
        self.setSceneRect(0, 0, 640, 480)
        self.setItemIndexMethod(QGraphicsScene.NoIndex)
        self.setBackgroundBrush(QBrush(Qt.black))


class GraphicsView(QGraphicsView):
    def __init__(self, parent=None):
        super(GraphicsView, self).__init__(parent)
        self.setScene(GraphicsScene(self))
        self.setAcceptDrops(True)
        self.setRenderHint(QPainter.HighQualityAntialiasing)

    def dragMoveEvent(self, event):
        if event.mimeData().hasImage():
            event.acceptProposedAction()

    def dropEvent(self, event):
        if event.mimeData().hasImage():
            pixmap = event.mimeData().imageData()
            if self.scene() is not None:
                it = self.scene().addPixmap(pixmap)
                it.setPos(self.mapToScene(event.pos()))
            event.acceptProposedAction()


class ImageWidget(QWidget):
    def __init__(self, imagePath, parent=None):
        super(ImageWidget, self).__init__(parent)
        self.picture = QPixmap(imagePath)

    def paintEvent(self, event):
        painter1 = QPainter(self)
        painter1.drawPixmap(0, 0, self.picture)

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            drag = QDrag(self)
            mimeData = QMimeData()
            mimeData.setImageData(self.picture)
            drag.setMimeData(mimeData)
            drag.setPixmap(self.picture)
            drag.setHotSpot(event.pos())
            drag.exec_()


class DragTableItem(QTableWidget):
    def __init__(self, parent=None):
        super(DragTableItem, self).__init__(parent)
        self.setRowCount(20)
        self.setColumnCount(2)

        col = "FlipHor"
        newItem = QTableWidgetItem(col)
        self.setImage(0, 1, "symbol.png")

    def setImage(self, row, col, imagePath):
        image = ImageWidget(imagePath)
        self.setCellWidget(row, col, image)


class DragWindow(QWidget):
    def __init__(self, parent=None):
        super(DragWindow, self).__init__(parent)
        lay = QVBoxLayout(self)
        lay.setSpacing(0)
        lay.setContentsMargins(0, 0, 0, 0)
        self.tableitem = DragTableItem()
        self.tableitem.setMinimumSize(300,300)
        lay.addWidget(self.tableitem)


class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.view = GraphicsView()
        self.table = DragWindow()

        widget = QWidget()
        self.setCentralWidget(widget)

        horizontalLayout = QHBoxLayout(widget)
        horizontalLayout.addWidget(self.table)
        horizontalLayout.addWidget(self.view)

        self.resize(640, 480)


if __name__ == "__main__":
    import sys

    app = QApplication(sys.argv)
    mainWindow = MainWindow()

    mainWindow.show()

    sys.exit(app.exec_())

有关在Qt上拖放的完整指南是here