一、简述
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 的堆叠顺序及其所有权。