用鼠标移动将QLabel移到绝对位置

时间:2019-04-22 00:39:53

标签: python pyqt pyqt5

我想用鼠标移动QLabel(与拖放不同,“ object”在移动时消失了)。单击-移动-释放。我做到了一定程度,但遇到了问题。 QLabel在我移动时会缩小甚至消失(例如缩小到0宽度)。如何解决它,或更正确的方法呢?

(需要self.label_pos来保持鼠标相对于self.label内部的位置)

还是它的显示器的刷新率问题?但是在photoshop的渐变编辑器中,很少的色标不是shrikns。由于刷新率不稳定,但大小始终相同。

这是我想使用屏幕捕获程序记录的内容。我在Photoshop中看到的同样的东西

这就是我所看到的,记录在我的手机上。质量很差,但是无论如何区别还是显而易见的。

此Photoshop也在我的手机上被捕获,这里的“对象”保持不变,与使用屏幕捕获的示例一样

这是从eyllanesc的答案得到的代码,“对象”仍然缩小了:(

self.label = QLabel(self)
self.label.move(100, 100)
self.label.mousePressEvent = self.mouse_on
self.label.mouseReleaseEvent = self.mouse_off
    def mouse_on(self, event):
        self.bool = True
        self.label_pos = event.pos()

    def mouse_off(self, event):
        self.bool = False

    def mouseMoveEvent(self, event):
        if self.bool:
            self.label.move(event.x()-self.label_pos.x(), event.y()-self.label_pos.y())

1 个答案:

答案 0 :(得分:1)

我建议不要将QGraphicsRectItem与QGraphicsView一起使用,因为它专门用于此类任务:

from PyQt5 import QtCore, QtGui, QtWidgets


class Widget(QtWidgets.QGraphicsView):
    def __init__(self, parent=None):
        super(Widget, self).__init__(parent)
        self.setScene(QtWidgets.QGraphicsScene(self))
        self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        brush = QtWidgets.QApplication.palette().brush(QtGui.QPalette.Window)
        self.setBackgroundBrush(brush)

        rect_item = self.scene().addRect(
            QtCore.QRectF(QtCore.QPointF(), QtCore.QSizeF(40, 80))
        )
        rect_item.setFlag(QtWidgets.QGraphicsItem.ItemIsMovable, True)
        rect_item.setBrush(QtGui.QBrush(QtGui.QColor("red")))


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = Widget()
    w.setFixedSize(640, 480)
    w.show()
    sys.exit(app.exec_())

如果只想水平滚动,则覆盖QGraphicsItem的itemChange方法:

from PyQt5 import QtCore, QtGui, QtWidgets


class HorizontalItem(QtWidgets.QGraphicsRectItem):
    def __init__(self, rect, parent=None):
        super(HorizontalItem, self).__init__(rect, parent)
        self.setFlag(QtWidgets.QGraphicsItem.ItemIsMovable, True)
        self.setFlag(QtWidgets.QGraphicsItem.ItemSendsGeometryChanges, True)

    def itemChange(self, change, value):
        if (
            change == QtWidgets.QGraphicsItem.ItemPositionChange
            and self.scene()
        ):
            return QtCore.QPointF(value.x(), self.pos().y())
        return super(HorizontalItem, self).itemChange(change, value)


class Widget(QtWidgets.QGraphicsView):
    def __init__(self, parent=None):
        super(Widget, self).__init__(parent)
        self.setScene(QtWidgets.QGraphicsScene(self))
        self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        brush = QtWidgets.QApplication.palette().brush(QtGui.QPalette.Window)
        self.setBackgroundBrush(brush)

        rect_item = HorizontalItem(
            QtCore.QRectF(QtCore.QPointF(), QtCore.QSizeF(40, 80))
        )
        rect_item.setBrush(QtGui.QBrush(QtGui.QColor("red")))
        self.scene().addItem(rect_item)


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = Widget()
    w.setFixedSize(640, 480)
    w.show()
    sys.exit(app.exec_())

在下面的代码中,有一个类似于您想要的示例:

from PyQt5 import QtCore, QtGui, QtWidgets


class HorizontalItem(QtWidgets.QGraphicsRectItem):
    def __init__(self, rect, parent=None):
        super(HorizontalItem, self).__init__(rect, parent)
        self.setFlag(QtWidgets.QGraphicsItem.ItemIsMovable, True)
        self.setFlag(QtWidgets.QGraphicsItem.ItemSendsGeometryChanges, True)

    def itemChange(self, change, value):
        if (
            change == QtWidgets.QGraphicsItem.ItemPositionChange
            and self.scene()
        ):
            return QtCore.QPointF(value.x(), self.pos().y())
        return super(HorizontalItem, self).itemChange(change, value)


class Widget(QtWidgets.QGraphicsView):
    def __init__(self, parent=None):
        super(Widget, self).__init__(parent)
        self.setScene(QtWidgets.QGraphicsScene(self))
        self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        brush = QtWidgets.QApplication.palette().brush(QtGui.QPalette.Window)
        self.setBackgroundBrush(brush)
        self.setFixedSize(640, 480)

        size = self.mapToScene(self.viewport().rect()).boundingRect().size()
        r = QtCore.QRectF(QtCore.QPointF(), size)
        self.setSceneRect(r)

        rect = QtCore.QRectF(
            QtCore.QPointF(), QtCore.QSizeF(0.8 * r.width(), 80)
        )
        rect.moveCenter(r.center())
        rect_item = self.scene().addRect(rect)
        rect_item.setBrush(QtGui.QBrush(QtGui.QColor("salmon")))
        item = HorizontalItem(
            QtCore.QRectF(
                rect.bottomLeft() + QtCore.QPointF(0, 20), QtCore.QSizeF(20, 40)
            )
        )
        item.setBrush(QtGui.QBrush(QtGui.QColor("red")))
        self.scene().addItem(item)


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())