Sure! My solution is below. <code> from math import sqrt from sys import argv
from PyQt4.Qt import QApplication from PyQt4.QtCore import QPoint, 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): point = self.mapToScene(QPoint(x, y)) self.unselect_items() for item in self.items(): if item.contains_point(point.x(), point.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> On Sat, Apr 13, 2013 at 6:52 PM, Christophe BAL <projet...@gmail.com> wrote: > Hello, > can you give your solution ? > > Christophe. > > > 2013/4/14 Tom Brown <nextst...@gmail.com> > >> 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 >> > >
_______________________________________________ PyQt mailing list PyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt