pythonpyqtqpolygon

Finding if a QPolygon contains a QPoint - Not giving expected results


I am working on a program in PyQt and creating a widget that displays a grid and a set of polygons on that grid that you are able to move around and click on. When I try to implement the clicking of the polygon, it does not seem to work. Below is the function that does not work:

def mouseMoveCustom(self, e):
    for poly in reversed(self.polys):
        if poly.contains(e.pos()):
            self.cur_poly = poly
            self.setCursor(Qt.PointingHandCursor)
            print('mouse cursor in polygon')
            break
        else:
            self.setCursor(Qt.CrossCursor)

For context, self.polys is a list of QPolygons and e.pos() is the mouse position. I have tried entering

print(poly)
print(poly.contains(QPoint(1,1)))

to test if it would work for a control point, but in the console, it only gives me this:

<PySide.QtGui.QPolygon(QPoint(50,350) QPoint(50,0) QPoint(0,0) QPoint(0,350) )  at 0x000000000547D608>
False

Is there something I am doing wrong here, or how can I convert the above "polygon" into an actual QPolygon that I can work with?

EDIT:

This is the code used to generate the list self.polys:

self.polys.append(QPolygon([QPoint(points[i][X]+self.transform[X], points[i][Y]+self.transform[Y]) for i in range(len(points))]))

Could it perhaps be a problem with using an inline for loop to add the QPolygons to the list?


Solution

  • The reason this is not working is because bool QPolygon.contains( QPoint ) returns true if the point is one of the vertices of the polygon, or if the point falls on the edges of the polygon. Some examples of points that would return true with your setup would be QPoint(0,0), QPoint(0,200), or anything that does match either of those criteria.

    What you are looking for, presumably, is a function that returns true if the point resides within the polygon, rather than on it. The function you are looking for is QPolygon.containsPoint ( QPoint , Qt.FillRule ). The point is as you think it is, and the second value is either a 1 or a 0 (represented as either Qt.OddEvenFill or Qt.WindingFill respectively), which determine what method of finding whether or not a point is inside a polygon. Information about Qt.FillRule can be found here: https://doc.qt.io/archives/qtjambi-4.5.2_01/com/trolltech/qt/core/Qt.FillRule.html

    corrected code:

    print(poly)
    print(poly.containsPoint(QPoint(1,1), Qt.OddEvenFill))