Pyqt4:如何纠正QGraphicsItem的位置?

时间:2015-02-05 16:55:28

标签: position pyqt4 qgraphicsview qgraphicsitem

我试图在QGraphicsView上绘制路径。但是,这个立场似乎不对。第一个点(红色)是(0,0),它应该位于左上角。如何将绘图移动到正确的位置?

from PyQt4 import QtGui, QtCore
from PyQt4.QtCore import QPointF as qpf
import sys
from PyQt4.QtGui import QPainterPath

data= [qpf(0,0),qpf(40,30),qpf(30,60),qpf(70,90),qpf(20,120),qpf(60,150)]   

class Window(QtGui.QWidget):
    def __init__(self):
        QtGui.QWidget.__init__(self)
        self.view = View(self)
        layout = QtGui.QVBoxLayout(self)
        layout.addWidget(self.view)

class View(QtGui.QGraphicsView):
    def __init__(self, parent):
        QtGui.QGraphicsView.__init__(self, parent)
        self.setScene(QtGui.QGraphicsScene(self))
        item = QtGui.QGraphicsRectItem(data[0].x()-2,data[0].y()-2,4,4)
        item.setBrush(QtCore.Qt.red)
        self.scene().addItem(item)
        self.path = path = QPainterPath(data[0])
        for d in data[1:]:
            path.lineTo(d)
        item = QtGui.QGraphicsPathItem(path)
        self.scene().addItem(item)


    def mouseReleaseEvent(self, event):
        pos = event.pos()
        rect = QtCore.QRectF(pos.x()-2, pos.y()-2,4,4)
        item = QtGui.QGraphicsRectItem(rect)
        self.scene().addItem(item)

        if self.path.intersects(rect):
            print 'on line'
        else:
            print 'Not belong to line (%d, %d)' % (pos.x(), pos.y())

        QtGui.QGraphicsView.mouseReleaseEvent(self, event)


if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    window = Window()
    window.resize(400, 400)
    window.show()
    sys.exit(app.exec_())

2 个答案:

答案 0 :(得分:0)

这种行为是因为您使用QGraphicsScene和QGraphicsView进行绘制。这是因为视图和场景具有一些自动性,通常非常方便。协调的场景可以与视图完全不同(以像素为单位)。

docs:“调用sh​​ow()后,默认情况下,视图将滚动到场景中心并显示此时可见的所有项目。”在您的情况下隐式调用show(),我相信在您向场景添加项目之后。

我可以想到两种可能性来获得你想要的东西:

1)将视图更改为场景,以便场景坐标(0,0)位于视图的左上角。

2)不要使用QGraphicsScene和QGraphicsView,而只是从其绘图事件中绘制一个小部件,如示例here所示。这意味着您的尺寸都是以像素为单位,即您的点的坐标是像素。并且没有可能使您感到困惑的自动化。

答案 1 :(得分:0)

您希望在视图类构造函数中使用self.setAlignment(QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop),这将使0,0个场景坐标与视图坐标中的0,0相同。AlignmentFlag

我还建议在mouseReleaseEvent中使用pos = self.mapToScene(event.pos())。这样,如果您放大或滚动场景,点击将发生在视图中的正确位置。 QGraphicsView.mapFromScene