如何拖动按钮

2024-06-08 02:30:43 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在制作一个图像&;使用qToolButton和QRubberBand标记小部件,但是拖动在窗口中效果很好,但是拖动在按钮上不起作用。有解决办法吗

# coding:utf-8
from PySide2 import QtCore,QtGui,QtWidgets

class QToolButton(QtWidgets.QToolButton):
    def __init__(self, label='', icon=''):
        super(QToolButton, self).__init__()
        self.label = label
        self.icon = icon
        self.create()

    def create(self):
        self.setText(self.label)
        self.setIcon(QtGui.QIcon(self.icon))
        self.setIconSize(QtCore.QSize(200, 200))
        self.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon)
        self.setCheckable(True)
        self.setFocusPolicy(QtCore.Qt.NoFocus)

class Window(QtWidgets.QWidget):
    def __init__(self):
        super(Window, self).__init__()
        self.rubberBand = QtWidgets.QRubberBand(QtWidgets.QRubberBand.Rectangle, self)
        self.resize(500, 300)
        layout = QtWidgets.QHBoxLayout(self)
        for i in range(5):
            layout.addWidget(QToolButton(label='test', icon='test.jpg'))

        self.setLayout(layout)
        self.setWindowTitle("Flow Layout")

    def mousePressEvent(self, event):
        self.origin = event.pos()
        self.rubberBand.setGeometry(
            QtCore.QRect(self.origin, QtCore.QSize()))
        self.rubberBand.show()
        QtWidgets.QWidget.mousePressEvent(self, event)

    def mouseMoveEvent(self, event):
        if self.rubberBand.isVisible():
            self.rubberBand.setGeometry(
                QtCore.QRect(self.origin, event.pos()).normalized())
        QtWidgets.QWidget.mouseMoveEvent(self, event)

    def mouseReleaseEvent(self, event):
        if self.rubberBand.isVisible():
            self.rubberBand.hide()
            selected = []
            rect = self.rubberBand.geometry()
            for child in self.findChildren(QtWidgets.QToolButton):
                if rect.intersects(child.geometry()):
                    selected.append(child)
            if selected:
                for i in selected:
                    if i.isChecked():
                        i.setChecked(False)
                    else:
                        i.setChecked(True)
        QtWidgets.QWidget.mouseReleaseEvent(self, event)

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())

enter image description here

我正在制作一个图像&;使用qToolButton和QRubberBand标记小部件,但是拖动在窗口中效果很好,但是拖动在按钮上不起作用。有解决办法吗


Tags: selfeventifinitdefwindowlabelicon
1条回答
网友
1楼 · 发布于 2024-06-08 02:30:43

您必须在要提供该功能的所有小部件上安装事件过滤器,并可能对橡皮筋使用公共函数以避免重复代码

class Window(QtWidgets.QWidget):
    def __init__(self):
        super(Window, self).__init__()
        self.rubberBand = QtWidgets.QRubberBand(QtWidgets.QRubberBand.Rectangle, self)
        self.resize(500, 300)
        layout = QtWidgets.QHBoxLayout(self)
        for i in range(5):
            button = QToolButton(label='test', icon='test.jpg')
            layout.addWidget(button)
            button.installEventFilter(self)

        self.setLayout(layout)
        self.setWindowTitle("Flow Layout")

    def eventFilter(self, source, event):
        if event.type() == event.MouseButtonPress:
            self.origin = source.mapTo(self, event.pos())
        elif event.type() == event.MouseMove and event.buttons():
            if not self.rubberBand.isVisible():
                distance = (source.mapTo(self, event.pos()) - self.origin).manhattanLength()
                if distance > QtWidgets.QApplication.startDragDistance():
                    if isinstance(source, QtWidgets.QAbstractButton) and source.isDown():
                        source.setDown(False)
                    self.rubberBand.show()
            if self.rubberBand.isVisible():
                self.resizeRubberBand(source.mapTo(self, event.pos()))
                event.accept()
                return True
        elif event.type() == event.MouseButtonRelease and self.rubberBand.isVisible():
            self.closeRubberBand()
            event.accept()
            return True
        return super().eventFilter(source, event)

    def startRubberBand(self, pos):
        self.origin = pos
        self.rubberBand.setGeometry(
            QtCore.QRect(self.origin, QtCore.QSize()))
        self.rubberBand.show()

    def resizeRubberBand(self, pos):
        if self.rubberBand.isVisible():
            self.rubberBand.setGeometry(
                QtCore.QRect(self.origin, pos).normalized())

    def closeRubberBand(self):
        if self.rubberBand.isVisible():
            self.rubberBand.hide()
            selected = []
            rect = self.rubberBand.geometry()
            for child in self.findChildren(QtWidgets.QToolButton):
                if rect.intersects(child.geometry()):
                    selected.append(child)
            if selected:
                for i in selected:
                    if i.isChecked():
                        i.setChecked(False)
                    else:
                        i.setChecked(True)

    def mousePressEvent(self, event):
        self.startRubberBand(event.pos())
        QtWidgets.QWidget.mousePressEvent(self, event)

    def mouseMoveEvent(self, event):
        self.resizeRubberBand(event.pos())
        QtWidgets.QWidget.mouseMoveEvent(self, event)

    def mouseReleaseEvent(self, event):
        self.closeRubberBand()
        QtWidgets.QWidget.mouseReleaseEvent(self, event)

请注意,您可能应该通过检查所有三个鼠标事件是否由左键生成来创建、调整和关闭rubberband;在这种情况下,请记住,对于mouseMoveEvent,应该使用buttons(),而不是button()

相关问题 更多 >

    热门问题