一、简述

QGraphicsWidget 继承自 QObject 和 QGraphicsItem,是 QGraphicsScene 中所有 widget items 的基类。

QGraphicsWidget 建立在 QGraphicsItem 之上,具有 QGraphicsItem 的所有功能。它保持了较小的资源占用,同时提供了两者的优点:

  • 来自 QWidget 的额外功能,例如:样式、字体、调色板、布局、几何形状。
  • 来自 QGraphicsItem 的分辨率独立性和坐标转换的支持。由于 Graphics View 使用真实的坐标而不是整数,因此 QGraphicsWidget 的 geometry 函数可以在 QRectF 和 QPointF 上操作。同时也能应用到边框的大小、边距和间距上。对于 QGraphicsWidget,规定内容边距为 (0.5, 0.5, 0.5, 0.5) 是非常常见的。例如:可以创建子部件和“顶级”窗口。在某些情况下,甚至可以将图形视图用于高级多文档界面的应用程序。

    二、QGraphicsWidget 和 QWidget 的相似点

    QGraphicsWidget 是一个扩展的基础 item,提供了 QGraphicsItem 额外的功能。它在很多方面类似于 QWidget:

  • 提供调色板(palette)、字体(font)和 style()

  • 有一个定义的 geometry()
  • 支持使用 setLayout() 和 layout() 的布局
  • 支持使用 grabShortcut() 和 insertAction() 的快捷方式和操作

由于 QGraphicsWidget 类似于 QWidget,并有着相似的 API,更容易从 QWidget 到 QGraphicsWidget,而不是 QGraphicsItem。

注意:基于 QWidget 的部件可以使用 QGraphicsProxyWidget 直接嵌入到 QGraphicsScene 中。

三、QGraphicsWidget 和 QWidget 的差异

除了相似之处,QGraphicsWidget 和 QWidget 之间也存在着显著的差异。

QGraphicsWidget QWidget
坐标和geometry用qreals定义(doubles或floats,取决于平台) QWidget 使用整数 geometry(QPoint、QRect)
默认情况下,窗口部件可见,不必调用 show() 来显示 QWidget 默认隐藏,直到调用 show()
支持部分 widget 属性  支持所有 widget 属性
顶级 item 的样式默认为 QGraphicsScene::style 顶级 widget 的样式默认为 QApplication::style
Graphics View 提供了一个自定义的拖放框架,不同于 QWidget  标准的拖放框架
Widget items 不支持模态 全模态支持

QGraphicsWidget 支持部分 QWidget 属性(Qt::WidgetAttribute),如下表所示(此表中未列出的任何属性都不受支持或未使用)。

Widget 属性 用法
Qt::WA_SetLayoutDirection 由 setLayoutDirection() 设置,由 unsetLayoutDirection() 清除。可以测试此属性以检查 widget 是否已显式分配了 layoutDirection。如果未设置属性,则继承 layoutDirection()。
Qt::WA_RightToLeft 由 setLayoutDirection() 切换。从 parent/scene 继承。 如果设置,widget 的布局将从右到左排序水平排列。
Qt::WA_SetStyle 由 setStyle() 设置和清除。如果设置了此属性,则已经为 widget 显式分配了样式;如果未设置,widget 将使用 scene 或 application 的样式。
Qt::WA_Resized 由 setGeometry() 和 resize() 设置
Qt::WA_SetPalette 由 setPalette() 设置
Qt::WA_SetFont 由 setFont() 设置
Qt::WA_WindowPropagation 启用传播至窗体 widgets

四、部件和布局

与 QGraphicsItem 不同,QGraphicsWidget 不是一个抽象类,我们可以创建一个 QGraphicsWidget 实例,而不必子类化它。该方法对于仅用于将子 widgets 组织到一个布局中的 widgets 非常有用。
首先,我们基于 QWidget 构建了 QLabel、QLineEdit 等基本部件,使用 QGraphicsScene::addWidget() 直接将他们嵌入到 QGraphicsScene 中,同时返回对应的 QGraphicsProxyWidget。然后通过 QGraphicsGridLayout 将 QGraphicsProxyWidget 添加至网格布局中,再将网格布局添加至 QGraphicsWidget。最后将其添加至视图中,利用 QGraphicsView 显示出来。

如果需要高级输入焦点处理(例如,制表符焦点和激活或布局),QGraphicsWidget 可以作为自定义 item 的基本 item。

尽管 QGraphicsWidget 继承自 QObject 和 QGraphicsItem,也应该使用 QGraphicsItem 提供的函数,而不是 QObject,来管理父项和子项之间的关系。这些功能控制 items 的堆叠顺序及其所有权。