PyQt4:如何重新排序子部件?

PyQt4: How to reorder child widgets?

我想用PyQt4在Unreal游戏引擎中实现一个类似于蓝图编辑器的GUI程序。这是蓝图编辑器的示例:

首先,我创建了一个简单的容器小部件来放置所有组件(矩形)。然后我使用 QPainterPath 小部件绘制线来连接组件。由于用户可以通过拖放将组件放置在他们想要的任何位置,因此我在我的容器小部件中选择了绝对定位。这是示例代码:

class Component(QtGui.QWidget):
    """A simple rectangle."""
    def __init__(self, type_, parent=None):
        super(Component, self).__init__(parent)
        ...

class BezierPath(QtGui.QWidget):

    def __init__(self, start, end, parent=None):
        super(BezierPath, self).__init__(parent)
        self.setMinimumSize(300, 500)
        self._start = start
        self._end = end
        self._path = self._generate_path(self._start, self._end)
        self.setMinimumSize(
            abs(start.x()-end.x()), abs(start.y()-end.y()))

    def _generate_path(self, start, end):
        path = QtGui.QPainterPath()
        path.moveTo(start)
        central_x = (start.x()+end.x())*0.5
        path.cubicTo(
            QtCore.QPointF(central_x, start.y()),
            QtCore.QPointF(central_x, end.y()),
            end)
        return path

    def paintEvent(self, event):
        painter = QtGui.QPainter()
        painter.begin(self)
        pen = QtGui.QPen()
        pen.setWidth(3)
        painter.setPen(pen)
        painter.setRenderHint(QtGui.QPainter.Antialiasing, True)
        painter.drawPath(self._path)
        painter.end()

class Container(QtGui.QWidget):
    def add_component(self, component_type, position):
        component = Component(component_type, self)
        component.move(position)

    def add_connection(self, component_a, component_b):
        bezier_path = BezierPath(component_a.pos(), component_b.pose(), self)

问题是我想在组件下方显示线条,但组件是先创建的。有没有办法可以重新排序 Container 的子窗口小部件?我应该使用更好的方法来组织组件吗?

我自己找到了重新排序子窗口小部件的解决方案。我暂时将此答案标记为已接受。这不是一个完美的解决方案,所以如果有更好的答案,我会接受。无论如何,这是解决方案:

在qt4中widget有一个方法raise_(),这里我引用:

to raises this widget to the top of the parent widget's stack. After this call the widget will be visually in front of any overlapping sibling widgets.

因此,如果您想重新排序所有小部件,首先您要将所有子小部件的引用保存在您自己的列表或您选择的容器中。重新排序您自己容器中的所有小部件,然后以相反的顺序为每个小部件调用 raise_()