在QGraphicsScene中嵌入QWidget

简介: 简述图形视图对将任何 widget 嵌入到场景中提供了无缝的支持。可以嵌入简单的 widget,例如:QLineEdit、QPushButton;也可以是复杂的 widget,例如:QTabWidget,甚至是完整的主窗口。要将 widget 嵌入场景中,只需要简单地调用 QGraphicsScene::addWidget(),或者创建一个 QGraphicsProx

简述

图形视图对将任何 widget 嵌入到场景中提供了无缝的支持。可以嵌入简单的 widget,例如:QLineEdit、QPushButton;也可以是复杂的 widget,例如:QTabWidget,甚至是完整的主窗口。

要将 widget 嵌入场景中,只需要简单地调用 QGraphicsScene::addWidget(),或者创建一个 QGraphicsProxyWidget 对象并将 widget 手工地嵌入其中。

QGraphicsProxyWidget

QGraphicsProxyWidget 类提供了一个代理层,用于在 QGraphicsScene 中嵌入一个 QWidget。

QGraphicsProxyWidget 嵌入基于 QWidget 的部件,例如:QPushButton、QFontComboBox,甚至 QFileDialog、QGraphicsScene。它在两个对象之间转发事件,并在 QWidget 的基于整数的 geometry 和 QGraphicsWidget 的基于 qreal 的 geometry 之间进行转换。

QGraphicsProxyWidget 支持 QWidget 的所有核心功能,包括:Tab 焦点、键盘输入、拖放和弹出窗口。还可以嵌入复杂的 widget,例如:带有子 widget 的 widget。

QGraphicsProxyWidget 通过为每个 popup 创建一个子代理,来负责嵌入 widget 的 popup 孩子的自动嵌入。这意味着当嵌入的 QComboBox 显示其弹出列表时,会自动创建一个新的 QGraphicsProxyWidget,嵌入 popup 并正确定位。这只有当 popup 是嵌入的 widget 的孩子时才有效(例如: QToolButton::setMenu() 要求 QMenu 实例是 QToolButton 的孩子)。

使用 QGraphicsProxyWidget 嵌入 Widget

使用 QGraphicsProxyWidget 嵌入一个 widget 有两种方法:

  • 将一个 widget 指针和任何相关的 Qt::WindowFlags 传递给 QGraphicsScene::addWidget() - 最常用的方式。
  • 创建一个新的 QGraphicsProxyWidget,然后调用 setWidget() 嵌入一个 QWidget。

例如,在下面的代码段中,我们在代理中嵌入了一个 QGroupBox:

这里写图片描述

QGroupBox *pGroupBox = new QGroupBox();
QLabel *pTellLabel = new QLabel();
QLabel *pAddressLabel = new QLabel();
QLineEdit *pTellLineEdit = new QLineEdit();
QLineEdit *pAddressLineEdit = new QLineEdit();

pGroupBox->setTitle(QStringLiteral("联系方式"));
pTellLabel->setText(QStringLiteral("电话号码:"));
pAddressLabel->setText(QStringLiteral("居住地址:"));
pTellLineEdit->setPlaceholderText(QStringLiteral("手机/固话"));
pAddressLineEdit->setPlaceholderText(QStringLiteral("具体到门牌号"));

QFormLayout *pLayout = new QFormLayout;
pLayout->addRow(pTellLabel, pTellLineEdit);
pLayout->addRow(pAddressLabel, pAddressLineEdit);
pLayout->setSpacing(10);
pLayout->setMargin(20);
pGroupBox->setLayout(pLayout);

QGraphicsScene scene;
QGraphicsProxyWidget *pProxy = scene.addWidget(pGroupBox);

QGraphicsView view(&scene);
view.show();

QGraphicsProxyWidget 与 QWidget 共享所有权,因此,如果这两个 widget 中的任一个被销毁,另一个也将被自动销毁。

同步 Widget 状态

QGraphicsProxyWidget 保持其与嵌入的 widget 状态同步。例如,如果代理被隐藏或禁用,嵌入的 widget 也将被隐藏或禁用,反之亦然。

当 widget 通过调用 addWidget() 被嵌入时,QGraphicsProxyWidget 将 widget 的状态(例如:visible、enabled、geometry、size hints)复制到代理中,然后,两者将尽可能地保持同步。 默认情况下,当一个 widget 被嵌入到代理中后,widget 和代理都是可见的,因为 QGraphicsWidget 在创建时是可见的(不必调用 show())。如果显式隐藏嵌入的 widget ,代理也将变为不可见。

示例:

QGraphicsScene scene;

QLineEdit *edit = new QLineEdit;
QGraphicsProxyWidget *proxy = scene.addWidget(edit);

edit->isVisible();  // 返回 true
proxy->isVisible(); // 也返回 true

edit->hide();

edit->isVisible();  // 返回 false
proxy->isVisible(); // 也返回 false

QGraphicsProxyWidget 保持以下状态的对称性:

QWidget 状态 QGraphicsProxyWidget 状态 说明
QWidget::enabled QGraphicsProxyWidget::enabled 
QWidget::visible QGraphicsProxyWidget::visible 显式状态也是对称的
QWidget::geometry QGraphicsProxyWidget::geometry 当嵌入的 widget 可见时,Geometry 仅保证是对称的
QWidget::layoutDirection QGraphicsProxyWidget::layoutDirection 
QWidget::style QGraphicsProxyWidget::style 
QWidget::palette QGraphicsProxyWidget::palette 
QWidget::font QGraphicsProxyWidget::font 
QWidget::cursor QGraphicsProxyWidget::cursor 嵌入的 widget 覆盖代理光标,代理光标的改变依赖嵌入的子 widget 当前在鼠标下。
QWidget::sizeHint() QGraphicsProxyWidget::sizeHint() 嵌入的 widget 的所有大小提示功能均由代理转发
QWidget::getContentsMargins() QGraphicsProxyWidget::getContentsMargins() 通过 setWidget() 更新一次
QWidget::windowTitle QGraphicsProxyWidget::windowTitle 通过 setWidget() 更新一次

注意:当 widget 被嵌入时,QGraphicsScene 保持嵌入的 widget 在一个特殊的状态,防止它影响其他 widget(嵌入和非嵌入)。在此状态下,widget 在行为上可能与未嵌入时略有不同。

警告: QGraphicsProxyWidget 类是为了便于桥接 QWidgets 和 QGraphicsItems 而提供,不应该用于高性能场景。

目录
相关文章
WK
|
4月前
|
数据可视化 开发者 容器
QWidget类
QWidget 是 Qt 框架中的基础类,用于创建用户界面的可视化组件。它是所有 UI 组件的基类,提供绘制、布局、事件处理、样式设置和部件通信等功能。常见子类包括 QMainWindow、QDialog、QPushButton 等,支持灵活的窗口管理和丰富的用户交互。
WK
69 3
|
5月前
|
iOS开发 MacOS
(11)QWidget的使用(two)
本文介绍了如何在Qt框架中使用QWidget类来设置和获取窗口的图标和标题,以及如何进行窗口状态和不透明度的设置。
85 3
|
5月前
(10)QWidget的使用(one)
文章介绍了QWidget的使用,包括如何获取和设置QWidget的大小和位置、设置窗口固定大小、限定窗口大小、坐标系统转换、内容边距、鼠标指针形状以及自定义光标的使用。
124 0
(10)QWidget的使用(one)
|
7月前
Qt绘图之QWidget
Qt绘图之QWidget
117 1
|
10月前
|
存储 监控 图形学
【QT】GraphicsView、QGraphicsScene、QGraphicsEllipseItem的使用
【QT】GraphicsView、QGraphicsScene、QGraphicsEllipseItem的使用
548 0
|
数据可视化
[√]QGraphicsView / QGraphicsScene
[√]QGraphicsView / QGraphicsScene
182 0
|
索引
探索QTableWidget对单元格(QWidget/QTableWidgetItem)的内存管理[clearContents()]
1.clearContents() 会清除表格中的所有单元格内容,包括释放之前创建的QTableWidgetItem和通过 setCellWidget() 设置的 QWidget 对象,但是不指向nullptr并且是延时释放QWidget 的而QTableWidgetItem 立即释放; 2.使用 setItem 方法将一个 QTableWidgetItem 对象设置为表格中的一个单元格后,该对象的位置(即所在行的索引)不会改变。这意味着,如果之后将该对象设置为其他单元格,它的位置将保持不变; 3.而使用 setCellWidget 方法将一个QWidget对象设置单元格时,位置可能会改变
409 0
解决QT QGraphicsView提升到QChartView报错的问题
使用QT提供的QChartView来绘制图表,提升QGraphicsView控件继承QChartView后,然后将QGraphicsView提升到我们自己写的类,怎么才能确保提升后编译不报错呢。
237 0
|
存储 缓存 数据可视化
Qt开发技术:图形视图框架(二)场景QGraphicsScene、QGraphicsItem与QGraphicsView详解
Qt开发技术:图形视图框架(二)场景QGraphicsScene、QGraphicsItem与QGraphicsView详解
Qt开发技术:图形视图框架(二)场景QGraphicsScene、QGraphicsItem与QGraphicsView详解
关于 Qt场景QGraphicsScene中,添加QWidget窗口,QWidget窗口无法捕捉mouseReleaseEvent松开消息 的解决方法
关于 Qt场景QGraphicsScene中,添加QWidget窗口,QWidget窗口无法捕捉mouseReleaseEvent松开消息 的解决方法
关于 Qt场景QGraphicsScene中,添加QWidget窗口,QWidget窗口无法捕捉mouseReleaseEvent松开消息 的解决方法