我想拖放标签,这与我的代码一样,但是在移动标签时标签消失了。拖动标签时如何使标签可见?我正在使用QDrag复制内容。

我希望能够将这些标签拖动到具有多个插槽的盒子中,并在标签落入附近时将标签锁定到其中一个插槽中。由于标签在拖动时变得不可见,因此,当我放开鼠标按钮时,很难直观地看到将标签放到哪里。

from PySide import QtCore, QtGui

myMimeType = 'application/MyWindow'

class MyLabel(QtGui.QLabel):
    def __init__(self, parent):
        super(MyLabel, self).__init__(parent)

        self.setStyleSheet("""
            background-color: black;
            color: white;
            font: bold;
            padding: 6px;
            border-width: 2px;
            border-style: solid;
            border-radius: 16px;
            border-color: white;
        """)

    def mousePressEvent(self, event):
        itemData   = QtCore.QByteArray()
        dataStream = QtCore.QDataStream(itemData, QtCore.QIODevice.WriteOnly)
        dataStream.writeString(self.text())
        dataStream << QtCore.QPoint(event.pos() - self.rect().topLeft())
    print dataStream

        mimeData = QtCore.QMimeData()
        mimeData.setData(myMimeType, itemData)
        mimeData.setText(self.text())

        drag = QtGui.QDrag(self)
        drag.setMimeData(mimeData)
        drag.setHotSpot(event.pos() - self.rect().topRight())

        self.hide()

        if drag.exec_(QtCore.Qt.MoveAction | QtCore.Qt.CopyAction, QtCore.Qt.CopyAction) == QtCore.Qt.MoveAction:
            self.close()

        else:
            self.show()


class MyFrame(QtGui.QFrame):
    def __init__(self, parent=None):
        super(MyFrame, self).__init__(parent)

        self.setStyleSheet("""
            background-color: lightgray;
            border-width: 2px;
            border-style: solid;
            border-color: black;
            margin: 2px;
        """)

        y = 6
        for labelNumber in range(6):
            label = MyLabel(self)
            label.setText("Label #{0}".format(labelNumber))
            label.move(6, y)
            label.show()

            y += label.height() + 2

        self.setAcceptDrops(True)

    def dragEnterEvent(self, event):
        if event.mimeData().hasFormat(myMimeType):
            if event.source() in self.children():
                event.setDropAction(QtCore.Qt.MoveAction)
                event.accept()

            else:
                event.acceptProposedAction()

        else:
            event.ignore()

    def dropEvent(self, event):
        if event.mimeData().hasFormat(myMimeType):
            mime       = event.mimeData()
            itemData   = mime.data(myMimeType)
            dataStream = QtCore.QDataStream(itemData, QtCore.QIODevice.ReadOnly)

            text = QtCore.QByteArray()
            offset = QtCore.QPoint()
            dataStream >> text >> offset

            newLabel = MyLabel(self)
            newLabel.setText(event.mimeData().text())
            newLabel.move(event.pos() - offset)
            newLabel.show()

            if event.source() in self.children():
                event.setDropAction(QtCore.Qt.MoveAction)
                event.accept()

            else:
                event.acceptProposedAction()

        else:
            event.ignore()

class MyWindow(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(MyWindow, self).__init__(parent)

        self.myFrame = MyFrame(self)

        self.setCentralWidget(self.myFrame)

if __name__ == "__main__":
    import sys

    app = QtGui.QApplication(sys.argv)
    app.setApplicationName('MyWindow')

    main = MyWindow()
    main.resize(333, 333)
    main.move(app.desktop().screen().rect().center() - main.rect().center())
    main.show()

    sys.exit(app.exec_())

最佳答案

您必须保存小部件并将其设置在QDrag中:

from PySide import QtCore, QtGui

myMimeType = "application/MyWindow"


class MyLabel(QtGui.QLabel):
    def __init__(self, parent):
        super(MyLabel, self).__init__(parent)

        self.setStyleSheet(
            """
            background-color: black;
            color: white;
            font: bold;
            padding: 6px;
            border-width: 2px;
            border-style: solid;
            border-radius: 16px;
            border-color: white;
        """
        )

    def mousePressEvent(self, event):
        itemData = QtCore.QByteArray()
        dataStream = QtCore.QDataStream(itemData, QtCore.QIODevice.WriteOnly)
        dataStream.writeString(self.text())
        dataStream << QtCore.QPoint(event.pos() - self.rect().topLeft())

        mimeData = QtCore.QMimeData()
        mimeData.setData(myMimeType, itemData)
        mimeData.setText(self.text())

        drag = QtGui.QDrag(self)
        drag.setMimeData(mimeData)
        drag.setHotSpot(event.pos())
        # pixmap = self.grab()
        pixmap = QtGui.QPixmap(self.size())
        self.render(pixmap)
        drag.setPixmap(pixmap)
        self.hide()

        action = drag.exec_(
            QtCore.Qt.MoveAction | QtCore.Qt.CopyAction, QtCore.Qt.CopyAction
        )
        if action == QtCore.Qt.MoveAction:
            self.deleteLater()
        else:
            self.show()


class MyFrame(QtGui.QFrame):
    def __init__(self, parent=None):
        super(MyFrame, self).__init__(parent)

        self.setStyleSheet(
            """
            background-color: lightgray;
            border-width: 2px;
            border-style: solid;
            border-color: black;
            margin: 2px;
        """
        )

        y = 6
        for labelNumber in range(6):
            label = MyLabel(self)
            label.setText("Label #{0}".format(labelNumber))
            label.move(6, y)
            label.show()

            y += label.height() + 2

        self.setAcceptDrops(True)

    def dragEnterEvent(self, event):
        if event.mimeData().hasFormat(myMimeType):
            if event.source() in self.children():
                event.acceptProposedAction()

    def dropEvent(self, event):
        if event.mimeData().hasFormat(myMimeType):
            if (
                event.source() in self.children()
                and event.possibleActions() & QtCore.Qt.MoveAction
            ):
                event.acceptProposedAction()
                mime = event.mimeData()
                itemData = mime.data(myMimeType)
                dataStream = QtCore.QDataStream(itemData, QtCore.QIODevice.ReadOnly)

                text = QtCore.QByteArray()
                offset = QtCore.QPoint()
                dataStream >> text >> offset

                newLabel = MyLabel(self)
                newLabel.setText(event.mimeData().text())
                newLabel.move(event.pos() - offset)
                newLabel.show()
                event.setDropAction(QtCore.Qt.MoveAction)
        else:
            event.ignore()


class MyWindow(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(MyWindow, self).__init__(parent)
        self.myFrame = MyFrame()
        self.setCentralWidget(self.myFrame)


if __name__ == "__main__":
    import sys

    app = QtGui.QApplication(sys.argv)
    app.setApplicationName("MyWindow")
    main = MyWindow()
    main.resize(333, 333)
    main.show()
    sys.exit(app.exec_())

关于python - PySide当我拖放时如何保持QLabel可见?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59204784/

10-16 02:16