绘制延伸到其父项之外的 Qt 小部件的图表 window

Make a graph of Qt widgets that extend outside its parent window

我正在尝试为下图创建一个基本的 Qt 解决方案:

(在 post 的底部,我包含了一个嵌套的字典,如果有人想使用它,可以用来生成小部件图)

基本上,我需要某种小部件/小部件树,可以...

起初我想也许 QTreeWidget 或 QTreeView 可以做到这一点,但我无法让那些 类 扩展到主 window 之外,如图所示。

我还尝试在 QListWidget 中摆弄 QMenu 和 QMenuBar,然后是 QMenu 小部件。 None 产生了良好的结果。但我可能一直在错误地创建它们。

这是我需要在 Qt 中显示的一些数据:

[
    {
        'name': 'foo',
        'dependencies': [
            {
                'name': 'bar',
                'dependencies': [],
            },
            {
                'name': 'when',
                'dependencies': [
                    {
                        'name': 'subitem',
                        'dependencies': [],
                    },
                    {
                        'name': 'will',
                        'dependencies': [
                            {
                                'name': 'it',
                                'dependencies': [
                                    {
                                        'name': 'end',
                                        'dependencies': [],
                                        'version': 8,
                                        'latest': 10,
                                    },
                                ],
                            },
                        ],
                    },
                    {
                        'name': 'another',
                        'dependencies': [],
                    },
                ],
            },
            {
                'name': 'thing',
                'dependencies': [],
            },
        ],
    },
    {
        'name': 'some_other_thing',
        'dependencies': [],
    },
    {
        'name': 'an_asset_with_data',
        'dependencies': [],
    },
    {
        'name': 'more_things',
        'dependencies': [],
    },
]

如有任何帮助,我们将不胜感激。

我建议的解决方案是使用 QListWidgetQMenu

import sys

from PyQt4.QtCore import Qt
from PyQt4.QtGui import QApplication, QListWidget, QListWidgetItem, QMenu


class MenuWidget(QListWidget):
    DependenciesRole = Qt.UserRole

    def __init__(self, items, parent=None):
        QListWidget.__init__(self, parent)
        for it in items:
            name = it["name"]
            dependencies = it["dependencies"]
            it = QListWidgetItem(name)
            self.addItem(it)
            it.setData(MenuWidget.DependenciesRole, dependencies)

    def mousePressEvent(self, event):
        QListWidget.mousePressEvent(self, event)
        it = self.itemAt(event.pos())
        if it is not None:
            dependencies = it.data(MenuWidget.DependenciesRole)
            if dependencies:
                menu = QMenu(self)
                MenuWidget.add_submenu(menu, dependencies)
                p = self.visualRect(self.indexAt(event.pos())).topRight()
                menu.popup(self.mapToGlobal(p))

    @staticmethod
    def add_submenu(menu, items):
        for it in items:
            name = it["name"]
            dependencies = it["dependencies"]
            if dependencies:
                mn = menu.addMenu(name)
                MenuWidget.add_submenu(mn, dependencies)
            else:
                menu.addAction(name)


d = [
    {
        'name': 'foo',
        'dependencies': [
            {
                'name': 'bar',
                'dependencies': [],
            },
            {
                'name': 'when',
                'dependencies': [
                    {
                        'name': 'subitem',
                        'dependencies': [],
                    },
                    {
                        'name': 'will',
                        'dependencies': [
                            {
                                'name': 'it',
                                'dependencies': [
                                    {
                                        'name': 'end',
                                        'dependencies': [],
                                        'version': 8,
                                        'latest': 10,
                                    },
                                ],
                            },
                        ],
                    },
                    {
                        'name': 'another',
                        'dependencies': [],
                    },
                ],
            },
            {
                'name': 'thing',
                'dependencies': [],
            },
        ],
    },
    {
        'name': 'some_other_thing',
        'dependencies': [],
    },
    {
        'name': 'an_asset_with_data',
        'dependencies': [],
    },
    {
        'name': 'more_things',
        'dependencies': [],
    },
]

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = MenuWidget(d)
    w.show()
    sys.exit(app.exec_())