绘制延伸到其父项之外的 Qt 小部件的图表 window
Make a graph of Qt widgets that extend outside its parent window
我正在尝试为下图创建一个基本的 Qt 解决方案:
(在 post 的底部,我包含了一个嵌套的字典,如果有人想使用它,可以用来生成小部件图)
基本上,我需要某种小部件/小部件树,可以...
- 递归地从主 window 弹出(如图所示)
- 存储任意数据,以便我可以像在给定图像中那样设置不同的样式,或者为每个小部件提供不同的操作/工具提示等。
- 理想情况下,任何解决方案都应该使用某种视图,以便我可以与其他类型的显示器共享模型
起初我想也许 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': [],
},
]
如有任何帮助,我们将不胜感激。
我建议的解决方案是使用 QListWidget
和 QMenu
。
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_())
我正在尝试为下图创建一个基本的 Qt 解决方案:
(在 post 的底部,我包含了一个嵌套的字典,如果有人想使用它,可以用来生成小部件图)
基本上,我需要某种小部件/小部件树,可以...
- 递归地从主 window 弹出(如图所示)
- 存储任意数据,以便我可以像在给定图像中那样设置不同的样式,或者为每个小部件提供不同的操作/工具提示等。
- 理想情况下,任何解决方案都应该使用某种视图,以便我可以与其他类型的显示器共享模型
起初我想也许 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': [],
},
]
如有任何帮助,我们将不胜感激。
我建议的解决方案是使用 QListWidget
和 QMenu
。
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_())