首页 > 解决方案 > 从一个按钮拖放到另一个没有子类的按钮

问题描述

我想将颜色数据从按钮移动到按钮。
有没有其他方法可以使用 eventfilter 子类化按钮?
当 eventfilter 在按钮上安装EventFilter 时, event.pos() 值不同。

from PySide2 import QtWidgets, QtCore, QtGui
from functools import partial

class DragTest(QtWidgets.QMainWindow):

    def __init__(self):
        super(DragTest, self).__init__()

        cent = QtWidgets.QWidget()
        self.setCentralWidget(cent)

        layout = QtWidgets.QHBoxLayout(cent)
        self.color1_btn = QtWidgets.QPushButton()
        self.color1_btn.clicked.connect(partial(self.color_btn_click, widget=self.color1_btn))
        self.color2_btn = QtWidgets.QPushButton()
        self.color2_btn.clicked.connect(partial(self.color_btn_click, widget=self.color2_btn))
        layout.addWidget(self.color1_btn)
        layout.addWidget(self.color2_btn)

        self.btn1 = QtWidgets.QPushButton()
        self.btn2 = QtWidgets.QPushButton()
        layout.addWidget(self.btn1)
        layout.addWidget(self.btn2)

    def color_btn_click(self, widget):
        color = QtWidgets.QColorDialog.getColor()
        if color.isValid():
            print "red: {0}, green: {1}, blue: {2}".format(*color.getRgb())
            widget.setStyleSheet("background-color:rgb({0},{1},{2})".format(*color.getRgb()))
            widget.setProperty("color", color.getRgb())
    
    def eventFilter(self, obj, event):
        super(DragTest, self).eventFilter(obj, event)

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    win = DragTest()
    win.show()
    sys.exit(app.exec_())

标签: pythonpyside2

解决方案


eventFilter如果这是您的偏好,您可以设置拖动操作。确保acceptDrops按钮为 True,然后在事件过滤器中捕获鼠标移动和拖动事件。QMimeData 有一个colorData属性来存储 QColor 对象。

class DragTest(QtWidgets.QMainWindow):

    def __init__(self):
        super(DragTest, self).__init__()

        cent = QtWidgets.QWidget()
        self.setCentralWidget(cent)

        layout = QtWidgets.QHBoxLayout(cent)
        self.color1_btn = QtWidgets.QPushButton(acceptDrops=True)
        self.color1_btn.clicked.connect(partial(self.color_btn_click, widget=self.color1_btn))
        self.color2_btn = QtWidgets.QPushButton(acceptDrops=True)
        self.color2_btn.clicked.connect(partial(self.color_btn_click, widget=self.color2_btn))
        layout.addWidget(self.color1_btn)
        layout.addWidget(self.color2_btn)
        self.color1_btn.installEventFilter(self)
        self.color2_btn.installEventFilter(self)
        self.color1_btn.color = self.color2_btn.color = None

        self.btn1 = QtWidgets.QPushButton()
        self.btn2 = QtWidgets.QPushButton()
        layout.addWidget(self.btn1)
        layout.addWidget(self.btn2)

    def color_btn_click(self, widget):
        color = QtWidgets.QColorDialog.getColor()
        if color.isValid():
            self.set_color(widget, color)

    def set_color(self, widget, color):
        widget.setStyleSheet("background-color:rgb({0},{1},{2})".format(*color.getRgb()))
        widget.color = color
    
    def eventFilter(self, obj, event):
        if obj in {self.color1_btn, self.color2_btn}:
            if event.type() == QtCore.QEvent.MouseMove and obj.color:
                mimedata = QtCore.QMimeData()
                mimedata.setColorData(obj.color)
                
                pixmap = QtGui.QPixmap(20, 20)
                pixmap.fill(QtCore.Qt.transparent)
                painter = QtGui.QPainter(pixmap)
                painter.setRenderHint(QtGui.QPainter.Antialiasing)
                painter.setBrush(obj.color)
                painter.setPen(QtGui.QPen(obj.color.darker(150), 2))
                painter.drawEllipse(pixmap.rect().center(), 8, 8)
                painter.end()
                
                drag = QtGui.QDrag(obj)
                drag.setMimeData(mimedata)
                drag.setPixmap(pixmap)
                drag.setHotSpot(pixmap.rect().center())
                drag.exec_(QtCore.Qt.CopyAction)
                
            elif event.type() == QtCore.QEvent.DragEnter:
                event.accept() if event.mimeData().hasColor() else event.ignore()

            elif event.type() == QtCore.QEvent.Drop:
                self.set_color(obj, event.mimeData().colorData())
                event.accept()
                
        return super(DragTest, self).eventFilter(obj, event)

推荐阅读