Ah! I found the QGraphicsView.mapToScene() method. This solved my problem. Thanks! Tom
On Sat, Apr 13, 2013 at 6:06 PM, Tom Brown <nextst...@gmail.com> wrote: > I've found that this problem isn't specific to a bezier curve. If I change > the curve to a straight line, I observe the same problem. So, I would think > that it has something to do with the way I'm setting up the view. > > Any ideas would be appreciated. > > Thanks! > Tom > > > > On Sat, Apr 13, 2013 at 5:15 PM, Tom Brown <nextst...@gmail.com> wrote: > >> I've created a simple application (see below) that draws a bezier curve. >> I want to give the user the ability to select the curve so they can move it >> around. However, I'm having trouble selecting the curve in an intuitive >> fashion. When I click on the curve, the point I click on is actually far >> away from the curve. >> >> For example, when I click on the left end of the curve, the x-coordinate >> of the point where I clicked is about 100 pixels away from the x-coordinate >> of the point of the curve I clicked on. >> >> The code below demonstrates this problem. >> >> Any ideas why this is happening or what I'm doing wrong? >> >> Thanks! >> Tom >> >> <code> >> from math import sqrt >> from sys import argv >> >> from PyQt4.Qt import QApplication >> from PyQt4.QtCore import QPointF, Qt >> from PyQt4.QtGui import ( >> QColor, >> QGraphicsItem, >> QGraphicsView, >> QGraphicsScene, >> QPainterPath, >> ) >> >> >> class View(QGraphicsView): >> def __init__(self, parent=None): >> super(View, self).__init__(parent) >> self.epsilon = 11.0 >> self.graphics_scene = QGraphicsScene(self) >> self.setScene(self.graphics_scene) >> self.add_curve() >> >> def mousePressEvent(self, event): >> if event.button() == Qt.LeftButton: >> self.select_item_at(event.x(), event.y()) >> >> def select_item_at(self, x, y): >> self.unselect_items() >> for item in self.items(): >> if item.contains_point(x, y, self.epsilon): >> item.set_selected(True) >> item.update() >> >> def unselect_items(self): >> for item in self.items(): >> item.set_selected(False) >> item.update() >> >> def add_curve(self): >> color = QColor(255, 0, 0) >> x0 = 600.0 >> y0 = 400.0 >> x1 = 800.0 >> y1 = 500.0 >> x2 = 1000.0 >> y2 = 500.0 >> x3 = 1200.0 >> y3 = 400.0 >> control_points = (QPointF(x0, y0), QPointF(x1, y1), >> QPointF(x2, y2), QPointF(x3, y3)) >> curve = Curve(color, control_points) >> self.graphics_scene.addItem(curve) >> >> >> class Curve(QGraphicsItem): >> def __init__(self, color, control_points, parent=None, scene=None): >> super(Curve, self).__init__(parent, scene) >> self.selected = False >> self.color = color >> self.path = QPainterPath() >> self.path.moveTo(control_points[0]) >> self.path.cubicTo(*control_points[1:]) >> >> def set_selected(self, selected): >> self.selected = selected >> >> def contains_point(self, x, y, epsilon): >> p = (x, y) >> min_distance = float(0x7fffffff) >> t = 0.0 >> while t < 1.0: >> point = self.path.pointAtPercent(t) >> spline_point = (point.x(), point.y()) >> print p, spline_point >> distance = self.distance(p, spline_point) >> if distance < min_distance: >> min_distance = distance >> t += 0.1 >> print min_distance, epsilon >> return (min_distance <= epsilon) >> >> def boundingRect(self): >> return self.path.boundingRect() >> >> def paint(self, painter, option, widget): >> painter.setPen(self.color) >> painter.setBrush(self.color) >> painter.strokePath(self.path, painter.pen()) >> >> def distance(self, p0, p1): >> a = p1[0] - p0[0] >> b = p1[1] - p0[1] >> return sqrt(a * a + b * b) >> >> >> if __name__ == '__main__': >> app = QApplication(argv) >> view = View() >> view.setGeometry(100, 100, 1600, 900) >> view.setWindowTitle('MainWindow') >> view.show() >> app.exec_() >> >> </code> >> > >
_______________________________________________ PyQt mailing list PyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt