2015-02-05 7 views
2

Я пытаюсь нарисовать путь на QGraphicsView. Однако позиция кажется неправильной. Первая точка (красная) - (0,0), которая должна находиться в верхнем левом углу. Как перенести чертеж в нужное положение?Pyqt4: Как исправить положение QGraphicsItem?

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_()) 

ответ

0

Это поведение объясняется тем, что вы рисуете с использованием QGraphicsScene и QGraphicsView. Это связано с тем, что вид и сцена имеют некоторый автоматизм, которые очень удобны, как правило. Скоординированная сцена может полностью отличаться от представления (которое находится в пикселях).

От docs: «После того, как вы вызовеете show(), представление по умолчанию прокрутит до центра сцены и отобразит все элементы, которые видны на этом этапе». show() называется неявно в вашем случае, я считаю, что после добавления элемента в сцену.

я могу думать о двух возможностях, чтобы получить то, что вы хотите:

1) изменить вид на сцене, так что сцена-координаты (0, 0) находится в верхнем левом углу зрения.

2) НЕ используйте QGraphicsScene и QGraphicsView, но просто нарисуйте виджет из своего события рисования, как показано, например, here. Это означает, что ваши размеры все в пикселях, т. Е. Координаты ваших точек - это пиксели. И автоматизм, который может вас смутить, не будет выполнен.

0

Вы должны использовать self.setAlignment(QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop) в своем конструкторе класса вида, который сделает 0,0 координат сцены такими же, как 0,0 в координатах вида. AlignmentFlag

Я также предложил бы pos = self.mapToScene(event.pos()) в mouseReleaseEvent. таким образом, если вы увеличиваете или прокручиваете сцену, щелчок произойдет в нужном месте в представлении. QGraphicsView.mapFromScene