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

3
我希望使用PyQt4实现一个类似于虚幻游戏引擎蓝图编辑器的GUI程序。以下是蓝图编辑器的示例:

enter image description here

首先,我创建一个简单的容器小部件以放置所有组件(矩形)。然后,我使用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的子部件,或者我应该使用更好的方法来组织组件?

我最近做了类似的事情:我选择了 QGraphicsView 框架来实现它。也许值得考虑转换。QGraphicsView 允许轻松控制图形的呈现。我在研究过程中还发现了其他 UI 的称呼,比如基于流程的 UI、基于节点的 UI。很抱歉这不是答案,但我目前没有时间去研究你的代码。祝你好运! - Mailerdaimon
1
我也强烈建议使用QGraphicsView框架。它专为灵活的2D界面而设计。这里有一个节点链接图编辑器的示例:https://github.com/Werkov/PyQt4/blob/master/examples/graphicsview/diagramscene/diagramscene.py。如果您想嵌入更复杂的小部件,可以使用QGraphicsProxyWidgetItem(http://pyqt.sourceforge.net/Docs/PyQt4/qgraphicsproxywidget.html)。 - RickardSjogren
@Mailerdaimon @RickardSjogren 谢谢你们。我会看一下 QGraphicsView。同时,我找到了一个临时的解决方案:在 Container 中添加一个小部件,确保它在底部,然后将所有的 BezierPath 添加到该小部件中。 - kkpattern
1个回答

1
我找到了一个重新排列子部件的解决方案。暂时将此答案标记为已接受。如果有更好的答案,我会接受它。无论如何,以下是解决方案:
在qt4中,小部件有一个方法raise_(),引用如下:
“将该窗口部件提升到父窗口部件堆栈的顶部。调用此函数后,该窗口部件将在任何重叠的兄弟窗口部件前面可见。”
因此,如果要重新排序所有小部件,请首先将所有子小部件的引用保存在自己的列表或所选择的容器中。重新排列自己容器中的所有小部件,然后按相反的顺序为每个小部件调用raise_()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接