'Return an selection geometry covering item and all its children.'

def _selection_poly(self, item):

    def left(item):
        return [self._items[ch] for ch in item.node.branches[:1]]
    def right(item):
        return [self._items[ch] for ch in item.node.branches[(-1):]]
    itemsleft = list(preorder(item, left))[::(-1)]
    itemsright = list(preorder(item, right))
    assert itemsleft[0].node.is_leaf
    assert itemsright[(-1)].node.is_leaf
    if item.node.is_leaf:
        vert = [itemsleft[0].element.anchor]
    else:
        vert = []
        for it in itemsleft[1:]:
            vert.extend([it.element.path[0], it.element.path[1], it.element.anchor])
        for it in itemsright[:(-1)]:
            vert.extend([it.element.anchor, it.element.path[(-2)], it.element.path[(-1)]])
        vert.append(vert[0])
        def isclose(a, b, rel_tol=1e-06):
            return (abs((a - b)) < (rel_tol * max(abs(a), abs(b))))
        def isclose_p(p1, p2, rel_tol=1e-06):
            return (isclose(p1.x, p2.x, rel_tol) and isclose(p1.y, p2.y, rel_tol))
        acc = [vert[0]]
        for v in vert[1:]:
            if (not isclose_p(v, acc[(-1)])):
                acc.append(v)
        vert = acc
    return QPolygonF([QPointF(*p) for p in vert])
