使用QGraphicsWidget
在QGraphicsView框架中使用QGraphicsWidget
基本模式
一般来说, QGraphicsView
框架是用来显示图元的, 但是有的时候我们也需要能够在View里面显示一些控件. 这个时候, QGraphicsWidget
, 或者说QGraphicsProxyWidget
就派上用途了. 在大多数情况下, 它们还会需要和QGraphicsLayout
配合使用, 当然也可以不用.
这种使用方式和我们使用一般的Widget控件的模式也是基本类似的:
- 先创建一个
QGraphicWidget
的控件, 作为一个控件的容器, 就像我们创建一个QWidget
作为容器一样. - 再创建一个
QGraphicsLayout
的具体派生类示例, 作为布局 - 然后可以创建
QGraphicsProxyWidget
, 并添加到布局里面 - 最后, 将这个widget添加到
QGraphicsScene
里面:
例如, 下面的模式:
1 | // 创建一个QEdit和QPushButton控件 |
移动Widget
上面的使用方式下, 生成的QGraphicsWidget
的位置是固定死的. 如果我们需要将其能够拖动, 能够改变它们的大小, 还需要做额外的工作. 这里的核心主要有几点:
首先是
itemChange()
函数, 需要重载实现. 例如, 如果我们需要它们能够被拖动, 就需要处理QGraphicsItem::ItemPositionChange
和QGraphicsItem::ItemPositionChanged
.要让
QGraphicsWidget
的派生类处理itemChang()
, 我们要设置Flag. 例如:
1 | setFlags(QGraphicsItem::ItemIsMovable |
- 最后, 我们需要相应鼠标事件, 我们需要判断应该将鼠标事件转发给谁处理. 我们需要通过
QWidget::childAt()
来判断, 如果鼠标按下的是QWidget
的子类, 就将事件转发给QGraphicsProxyWidget
, 否则, 转发给QGraphicsItem
.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17void GraphicsProxyWidget::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
if(event->button() == Qt::LeftButton)
{
if(auto wdiget = this->widget()->childAt(pos.toPoint()))
{
QGraphicsProxyWidget::mousePressEvent(event);
//...
}
else
{
QGraphicsItem::mousePressEvent(event);
//..
}
}
//...
}
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 编程随笔!