#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Created on 2023/02/09
@author: Irony
@site: https://pyqt.site https://github.com/PyQt5
@email: 892768447@qq.com
@file: DragGraphics.py
@description:
"""

import json
import os

try:
    from PyQt5.QtCore import QMimeData, Qt
    from PyQt5.QtGui import QDrag, QIcon, QPixmap
    from PyQt5.QtWidgets import (QApplication, QGraphicsPixmapItem,
                                 QGraphicsScene, QGraphicsView, QHBoxLayout,
                                 QListWidget, QListWidgetItem, QTreeWidget,
                                 QTreeWidgetItem, QWidget)
except ImportError:
    from PySide2.QtCore import QMimeData, Qt
    from PySide2.QtGui import QDrag, QIcon, QPixmap
    from PySide2.QtWidgets import (QApplication, QGraphicsPixmapItem,
                                   QGraphicsScene, QGraphicsView, QHBoxLayout,
                                   QListWidget, QListWidgetItem, QTreeWidget,
                                   QTreeWidgetItem, QWidget)


class ListWidget(QListWidget):

    def __init__(self, *args, **kwargs):
        super(ListWidget, self).__init__(*args, **kwargs)
        self.setDragEnabled(True)
        self.setDragDropMode(QListWidget.DragOnly)
        self.setDefaultDropAction(Qt.IgnoreAction)
        self.setEditTriggers(QListWidget.NoEditTriggers)
        self.setResizeMode(QListWidget.Adjust)
        self.setViewMode(QListWidget.IconMode)

    def startDrag(self, supportedActions):
        items = self.selectedItems()
        if not items:
            return
        # 这里就简单的根据名字提示来传递数据了,实际上可以传递任意数据
        data = QMimeData()
        data.setData('application/node-items',
                     json.dumps([item.toolTip() for item in items]).encode())
        # 这里简单显示第一个缩略图
        pixmap = items[0].icon().pixmap(36, 36)
        drag = QDrag(self)
        drag.setMimeData(data)
        drag.setPixmap(pixmap)
        drag.setHotSpot(pixmap.rect().center())
        drag.exec_(supportedActions)


class GraphicsView(QGraphicsView):

    def __init__(self, *args, **kwargs):
        super(GraphicsView, self).__init__(*args, **kwargs)
        self.setAcceptDrops(True)
        self._scene = QGraphicsScene(self)  # 场景
        self.setScene(self._scene)

    def dragEnterEvent(self, event):
        """判断拖入的数据是否支持"""
        mimeData = event.mimeData()
        if not mimeData.hasFormat('application/node-items'):
            event.ignore()
            return

        event.acceptProposedAction()

    dragMoveEvent = dragEnterEvent

    def dropEvent(self, event):
        """获取拖拽的数据并绘制对于的图形"""
        datas = event.mimeData().data('application/node-items')
        datas = json.loads(datas.data().decode())
        print('datas:', datas)

        path = os.path.join(os.path.dirname(__file__), 'Data/icons')
        for name in datas:
            item = QGraphicsPixmapItem(QPixmap(os.path.join(path, name)))
            item.setFlags(QGraphicsPixmapItem.ItemIsFocusable |
                          QGraphicsPixmapItem.ItemIsMovable)
            self._scene.addItem(item)
            pos = self.mapToScene(event.pos())
            item.moveBy(pos.x(), pos.y())


class DragGraphics(QWidget):

    def __init__(self, *args, **kwargs):
        super(DragGraphics, self).__init__(*args, **kwargs)
        self.resize(800, 600)
        layout = QHBoxLayout(self)

        # 左侧树形控制
        self.treeWidget = QTreeWidget(self)
        self.treeWidget.header().setVisible(False)
        self.treeWidget.setMaximumWidth(300)
        layout.addWidget(self.treeWidget)

        # 右侧图形显示
        self.graphicsView = GraphicsView(self)
        layout.addWidget(self.graphicsView)

        self._init_trees()

    def _init_trees(self):
        """初始化树形控件中的图形节点列表"""
        # 1. 获取所有图标
        path = os.path.join(os.path.dirname(__file__), 'Data/icons')
        icons = [os.path.join(path, name) for name in os.listdir(path)]

        # 2. 添加根节点
        for i in range(2):
            item = QTreeWidgetItem(self.treeWidget)
            item.setText(0, 'View %d' % i)

            # 3. 添加子节点作为容器用于存放图标
            itemc = QTreeWidgetItem(item)
            child = ListWidget(self.treeWidget)
            self.treeWidget.setItemWidget(itemc, 0, child)

            # 4. 添加图标
            for icon in icons:
                item = QListWidgetItem(child)
                item.setIcon(QIcon(icon))
                item.setToolTip(os.path.basename(icon))

        self.treeWidget.expandAll()


if __name__ == '__main__':
    import cgitb
    import sys

    cgitb.enable(format='text')
    app = QApplication(sys.argv)
    w = DragGraphics()
    w.show()
    sys.exit(app.exec_())