文章目录
- 详述
- 公共类型
- 属性
- alignment: Qt::Alignment
- backgroundBrush: QBrush
- cacheMode: CacheMode
- dragMode: DragMode
- foregroundBrush: QBrush
- interactive: bool
- optimizationFlags: OptimizationFlags
- renderHints: QPainter::RenderHints
- resizeAnchor: ViewportAnchor
- rubberBandSelectionMode: Qt::ItemSelectionMode
- sceneRect: QRectF
- transformationAnchor: ViewportAnchor
- viewportUpdateMode: ViewportUpdateMode
- 公共函数
- 重写的公共函数
- 公共槽
- 信号
- 受保护的函数
- 重写的受保护的函数
- 受保护的槽
QGraphicsView 类
QGraphicsView类提供了一个小部件,用于显示QGraphicsScene的内容。
Header: | #include < QGraphicsView > |
---|---|
qmake: | QT += widgets |
Inherits: | QAbstractScrollArea |
Inherited By: | |
Since: | Qt 4.2 |
详述
QGraphicsView在可滚动视口中可视化QGraphicsScene的内容。 要创建带有几何项目的场景,请参见QGraphicsScene的文档。 QGraphicsView是Graphics View Framework的一部分。
为了使场景可视化,首先要构造一个QGraphicsView对象,然后将要可视化的场景的地址传递给QGraphicsView的构造函数。 另外,您可以调用setScene() 在以后设置场景。 调用show() 后,默认情况下,视图将滚动到场景的中心并显示此时可见的所有项目。 例如:
QGraphicsScene scene;
scene.addText("Hello, world!");
QGraphicsView view(&scene);
view.show();
可以使用滚动条或调用centerOn() 显式滚动到场景中的任何位置。通过将一个点传递给centerOn() ,QGraphicsView将滚动其视口以确保该点在视图中居中。提供了用于滚动到QGraphicsItem的重载,在这种情况下,QGraphicsView将看到项目的中心在视图中居中。如果您只想确保某个区域可见(但不一定居中) ,则可以调用sureVisible() 。
QGraphicsView可用于可视化整个场景或其中的一部分。默认情况下,第一次显示视图时,默认情况下会自动检测到可视化区域(通过调用QGraphicsScene::itemsBoundingRect() ) 。要自己设置可视化区域矩形,可以调用setSceneRect() 。这将适当地调整滚动条的范围。请注意,尽管场景实际上支持无限大小,但是滚动条的范围永远不会超出整数(INT_MIN,INT_MAX) 的范围。
QGraphicsView通过调用render() 可视化场景。默认情况下,将使用常规QPainter并使用默认的渲染提示将这些项目绘制到视口上。若要更改绘画项目时QGraphicsView传递给QPainter的默认渲染提示,可以调用setRenderHints() 。
默认情况下,QGraphicsView为视口窗口小部件提供常规的QWidget。您可以通过调用viewport() 来访问此小部件,也可以通过调用setViewport() 来替换它。要使用OpenGL渲染,只需调用setViewport(new QOpenGLWidget) 。 QGraphicsView拥有视口小部件的所有权。
QGraphicsView使用QTransform支持仿射变换。您可以将矩阵传递给setTransform() ,也可以调用便捷函数之一Rotate() ,scale() ,translate() 或shear() 。最常见的两种转换是缩放,用于实现缩放和旋转。 QGraphicsView在转换期间使视图的中心保持固定。由于场景对齐(setAligment() ) ,平移视图将不会产生视觉影响。
您可以使用鼠标和键盘与场景中的项目进行交互。 QGraphicsView将鼠标和键事件转换为场景事件(继承QGraphicsSceneEvent的事件) ,并将其转发到可视化场景。最后,处理事件并对事件做出反应的是单个项目。例如,如果单击一个可选项目,则该项目通常会让场景知道它已被选中,并且它还将重绘自身以显示选择矩形。类似地,如果单击并拖动鼠标以移动可移动项,则它是处理鼠标移动和自身移动的项。默认情况下,项目交互处于启用状态,您可以通过调用setInteractive() 进行切换。
您还可以通过创建QGraphicsView的子类并重新实现鼠标和键事件处理程序来提供自己的自定义场景交互。为了简化您如何以编程方式与视图中的项目进行交互,QGraphicsView提供了映射函数mapToScene() 和mapFromScene() 以及项目访问器items() 和itemAt() 。这些功能允许您在视图坐标和场景坐标之间映射点,矩形,多边形和路径,并使用视图坐标在场景中查找项目。
注意:使用OpenGL视口会限制使用QGraphicsProxyWidget的能力。 此类设置并非支持所有小部件和样式的组合。 您应该仔细测试您的UI并进行必要的调整。
另请参见QGraphicsScene,QGraphicsItem和QGraphicsSceneEvent。
公共类型
enum CacheModeFlag
flags CacheMode
该枚举描述了可以为QGraphicsView的缓存模式设置的标志。
Constant | Value | Description |
---|---|---|
QGraphicsView::CacheNone | 0x0 | 所有绘画都直接在视口上完成。 |
QGraphicsView::CacheBackground | 0x1 | 后台被缓存。 这会影响自定义背景以及基于backgroundBrush属性的背景。 启用此标志后,QGraphicsView将分配一个具有整个视口大小的像素图。 |
另请参见cacheMode。
enum DragMode
该枚举描述了在视口上按下并拖动鼠标时视图的默认操作。
Constant | Value | Description |
---|---|---|
QGraphicsView::NoDrag | 0 | 什么都没发生; 鼠标事件将被忽略。 |
QGraphicsView::ScrollHandDrag | 1 | 光标变为指向手,然后拖动鼠标将滚动滚动条。 此模式在交互和非交互模式下均有效。 |
QGraphicsView::RubberBandDrag | 2 | 出现橡皮筋。 拖动鼠标将设置橡皮筋的几何形状,并选中橡皮筋覆盖的所有项目。 非交互视图禁用此模式。 |
另请参见dragMode和QGraphicsScene::setSelectionArea() 。
enum OptimizationFlag
flags OptimizationFlags
该枚举描述了可以启用以改善QGraphicsView中的渲染性能的标志。 默认情况下,这些标志均未设置。 请注意,设置标志通常会产生副作用,并且此效果在绘画设备和平台之间可能会有所不同。
Constant | Value | Description |
---|---|---|
DontClipPainter | 0x1 | 此值已过时,并且无效。 |
DontSavePainterState | 0x2 | 渲染时,QGraphicsView在渲染背景或前景以及渲染每个项目时会保护画家状态(请参阅QPainter::save() )。这使您可以让画家保持更改的状态(即,您可以调用QPainter::setPen() 或QPainter::setBrush() ,而无需在绘画后恢复状态)。但是,如果项目确实确实恢复了状态,则应启用此标志,以防止QGraphicsView这样做。 |
DontAdjustForAntialiasing | 0x4 | 禁用QGraphicsView的曝光区域抗锯齿自动调整功能。在其QGraphicsItem::boundingRect() 的边界上呈现抗锯齿线的项目最终可能会在外部呈现线的一部分。为了防止呈现伪像,QGraphicsView将所有暴露区域在所有方向上扩大2个像素。如果启用此标志,则QGraphicsView将不再执行这些调整,从而最大程度地减少了需要重绘的区域,从而提高了性能。一个常见的副作用是,使用抗锯齿绘制的项目在移动时会在场景上留下绘画痕迹。 |
IndirectPainting | 0x8 | 从Qt 4.6开始,恢复调用QGraphicsView::drawItems() 和QGraphicsScene::drawItems() 的旧绘画算法。仅用于与旧代码兼容。 |
enum ViewportAnchor
该枚举描述了当用户调整视图大小或转换视图时QGraphicsView可以使用的锚点。
Constant | Value | Description |
---|---|---|
NoAnchor | 0 | 没有锚点,即视图使场景的位置保持不变。 |
AnchorViewCenter | 1 | 视图中心的场景点用作锚点。 |
AnchorUnderMouse | 2 | 鼠标下方的点用作锚点。 |
另请参见resizeAnchor和TransformationAnchor。
enum ViewportUpdateMode
该枚举描述了当场景内容更改或公开时QGraphicsView如何更新其视口。
Constant | Value | Description |
---|---|---|
FullViewportUpdate | 0 | 当场景的任何可见部分发生更改或重新曝光时,QGraphicsView将更新整个视口。当QGraphicsView花更多的时间来确定要绘制的内容比花在绘制上的时间多时(例如,当许多小物件被重复更新时),这种方法是最快的。对于不支持部分更新的视口(例如QOpenGLWidget)以及需要禁用滚动优化的视口,这是首选的更新模式。 |
MinimalViewportUpdate | 1 | QGraphicsView将确定需要重绘的最小视口区域,从而避免重绘未更改的区域,从而最大程度地减少了绘制时间。这是QGraphicsView的默认模式。尽管这种方法通常可以提供最佳的性能,但是如果场景中有许多可见的细微变化,则QGraphicsView最终可能会花费更多的时间来寻找最小的方法,而不是花在绘图上。 |
SmartViewportUpdate | 2 | QGraphicsView将通过分析需要重绘的区域来尝试找到最佳的更新模式。 |
NoViewportUpdate | 3 | 当场景改变时,QGraphicsView将永远不会更新其视口;用户应控制所有更新。此模式将禁用QGraphicsView中的所有(可能较慢的)项目可见性测试,并且适用于需要固定帧频或视口在外部进行更新的场景。 |
BoundingRectViewportUpdate | 4 | 视口中所有更改的边界矩形将被重绘。这种模式的优势在于QGraphicsView仅在一个区域中搜索更改,从而将确定所需重绘所需的时间最小化。缺点是未更改的区域也需要重新绘制。 |
另请参见viewportUpdateMode。
属性
alignment: Qt::Alignment
当整个场景可见时,此属性将保持场景在视图中的对齐方式。
如果整个场景在视图中可见(即,没有可见的滚动条),则视图的对齐方式将决定场景在视图中的渲染位置。 例如,如果对齐方式是Qt::AlignCenter(默认值),则场景将在视图中居中;如果对齐方式是(Qt::AlignLeft | Qt::AlignTop),则场景将在视图的左上角渲染。
Access functions:
- Qt::Alignment alignment() const
- void setAlignment(Qt::Alignment alignment)
backgroundBrush: QBrush
此属性保存场景的背景画笔。
此属性在此视图中设置场景的背景画笔。 它用于覆盖场景自己的背景,并定义drawBackground() 的行为。 要为此视图提供自定义背景图,您可以改为重新实现drawBackground() 。
默认情况下,此属性包含具有Qt::NoBrush模式的画笔。
Access functions:
- QBrush backgroundBrush() const
- void setBackgroundBrush(const QBrush &brush)
另请参见QGraphicsScene::backgroundBrush和foregroundBrush。
cacheMode: CacheMode
此属性保存视图的哪些部分被缓存
QGraphicsView可以将预渲染的内容缓存在QPixmap中,然后将其绘制到视口上。 这种缓存的目的是加快渲染速度较慢的区域的总渲染时间。 例如,纹理,渐变和Alpha混合背景的渲染速度可能非常慢; 尤其是在转换视图时。 CacheBackground标志启用对视图背景的缓存。 例如:
QGraphicsView view;
view.setBackgroundBrush(QImage(":/images/backgroundtile.png"));
view.setCacheMode(QGraphicsView::CacheBackground);
每次转换视图时,缓存都会失效。 但是,滚动时仅需要部分无效。
默认情况下,不缓存任何内容。
Access functions:
- QGraphicsView::CacheMode cacheMode() const
- void setCacheMode(QGraphicsView::CacheMode mode)
另请参见resetCachedContent() 和QPixmapCache。
dragMode: DragMode
此属性保留在按下鼠标左键时将鼠标拖到场景上的行为。
此属性定义了当用户单击场景背景并拖动鼠标时(例如,使用手形光标滚动视口内容或使用橡皮筋选择多个项目)时应该发生的情况。 默认值NoDrag不执行任何操作。
此行为仅影响任何项目均未处理的鼠标单击。 您可以通过创建QGraphicsView的子类并重新实现mouseMoveEvent() 来定义自定义行为。
Access functions:
- QGraphicsView::DragMode dragMode() const
- void setDragMode(QGraphicsView::DragMode mode)
foregroundBrush: QBrush
此属性保存场景的前景笔刷
默认情况下,此属性包含具有Qt::NoBrush模式的画笔。
Access functions:
- QBrush foregroundBrush() const
- void setForegroundBrush(const QBrush &brush)
另请参见QGraphicsScene::foregroundBrush和backgroundBrush。
interactive: bool
此属性保存视图是否允许场景交互。
如果启用,则此视图设置为允许场景交互。 否则,此视图将不允许交互,并且任何鼠标或按键事件都将被忽略(即,它将作为只读视图)。
默认情况下,此属性为true。
Access functions:
- bool isInteractive() const
- void setInteractive(bool allowed)
optimizationFlags: OptimizationFlags
可以用来调整QGraphicsView性能的标志。
QGraphicsView使用裁剪,额外的边界矩形调整和某些其他辅助手段来改善普通情况下图形场景的渲染质量和性能。 但是,根据使用的目标平台,场景和视口,这些操作中的某些操作可能会降低性能。
效果因标志而异; 有关详细信息,请参见OptimizationFlags文档。
默认情况下,不启用优化标志。
此属性在Qt 4.3中引入。
Access functions:
- QGraphicsView::OptimizationFlags optimizationFlags() const
- void setOptimizationFlags(QGraphicsView::OptimizationFlags flags)
另请参见setOptimizationFlag() 。
renderHints: QPainter::RenderHints
此属性保存视图的默认渲染提示
这些提示用于在绘制每个可见项之前初始化QPainter。 QPainter使用渲染提示来切换渲染功能,例如抗锯齿和平滑像素图转换。
QPainter::TextAntialiasing默认情况下处于启用状态。
QGraphicsScene scene;
scene.addRect(QRectF(-10, -10, 20, 20));
QGraphicsView view(&scene);
view.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
view.show();
Access functions:
- QPainter::RenderHints renderHints() const
- void setRenderHints(QPainter::RenderHints hints)
resizeAnchor: ViewportAnchor
调整视图大小时,视图应如何定位场景。
QGraphicsView使用此属性来决定当视口窗口小部件的大小改变时如何将场景放置在视口中。 默认行为NoAnchor在调整大小时使场景的位置保持不变。 调整大小时,视图的左上角将被锚定。
请注意,当只有一部分场景可见时(即,有滚动条时),此属性的效果很明显。 否则,如果整个场景都适合视图,则QGraphicsScene使用视图对齐将场景放置在视图中。
Access functions:
- QGraphicsView::ViewportAnchor resizeAnchor() const
- void setResizeAnchor(QGraphicsView::ViewportAnchor anchor)
另请参见alignment和transformationAnchor。
rubberBandSelectionMode: Qt::ItemSelectionMode
此属性保留选择带有橡皮筋选择矩形的项目的行为
此属性定义使用RubberBandDrag拖动模式时如何选择项目。
默认值为Qt::IntersectsItemShape; 选择形状与橡皮筋相交或包含在橡皮筋中的所有项目。
此属性在Qt 4.3中引入。
Access functions:
- Qt::ItemSelectionMode rubberBandSelectionMode() const
- void setRubberBandSelectionMode(Qt::ItemSelectionMode mode)
参见dragMode, items(), and rubberBandRect()。
sceneRect: QRectF
此属性保存此视图可视化的场景区域
场景矩形定义了场景的范围,在视图的情况下,这意味着可以使用滚动条导航的场景区域。
如果未设置,或者设置了null QRectF,则此属性的值与QGraphicsScene::sceneRect相同,并且随QGraphicsScene::sceneRect改变。 否则,视图的场景矩形将不受场景的影响。
请注意,尽管场景实际上支持无限大小,但是滚动条的范围永远不会超出整数(INT_MIN,INT_MAX)的范围。 当场景大于滚动条的值时,可以选择使用translate() 来导航场景。
默认情况下,此属性在原点包含一个宽度和高度为零的矩形。
Access functions:
- QRectF sceneRect() const
- void setSceneRect(const QRectF &rect)
- void setSceneRect(qreal x, qreal y, qreal w, qreal h)
transformationAnchor: ViewportAnchor
视图在转换过程中应如何定位场景。
QGraphicsView使用此属性来决定在变换矩阵发生变化以及视图的坐标系发生变换时如何在场景中放置场景。 默认行为AnchorViewCenter可确保在转换过程中视图中心的场景点保持不变(例如,旋转时,场景将围绕视图中心旋转)。
请注意,当只有一部分场景可见时(即,有滚动条时),此属性的效果很明显。 否则,如果整个场景都适合视图,则QGraphicsScene使用视图对齐将场景放置在视图中。
Access functions:
- QGraphicsView::ViewportAnchor transformationAnchor() const
- void setTransformationAnchor(QGraphicsView::ViewportAnchor anchor)
另请参见alignment和resizeAnchor。
viewportUpdateMode: ViewportUpdateMode
视口应如何更新其内容。
QGraphicsView使用此属性来决定如何更新已重新曝光或更改的场景区域。 通常,您不需要修改此属性,但是在某些情况下,这样做可以提高渲染性能。 有关特定的详细信息,请参见ViewportUpdateMode文档。
默认值为MinimalViewportUpdate,当内容更改时,QGraphicsView将在尽可能小的视口区域中进行更新。
此属性在Qt 4.3中引入。
Access functions:
- QGraphicsView::ViewportUpdateMode viewportUpdateMode() const
- void setViewportUpdateMode(QGraphicsView::ViewportUpdateMode mode)
另请参见ViewportUpdateMode和cacheMode。
公共函数
构造析构
- QGraphicsView(QGraphicsScene *scene, QWidget *parent = nullptr)
- QGraphicsView(QWidget *parent = nullptr)
- virtual ~QGraphicsView()
属性相关
- Qt::Alignment alignment() const
void setAlignment(Qt::Alignment alignment) - QBrush backgroundBrush() const
void setBackgroundBrush(const QBrush &brush) - QGraphicsView::CacheMode cacheMode() const
void setCacheMode(QGraphicsView::CacheMode mode) - QGraphicsView::DragMode dragMode() const
void setDragMode(QGraphicsView::DragMode mode) - QBrush foregroundBrush() const
void setForegroundBrush(const QBrush &brush) - bool isInteractive() const
void setInteractive(bool allowed) - QGraphicsView::OptimizationFlags optimizationFlags() const
void setOptimizationFlags(QGraphicsView::OptimizationFlags flags) - QPainter::RenderHints renderHints() const
void setRenderHints(QPainter::RenderHints hints) - QGraphicsView::ViewportAnchor resizeAnchor() const
void setResizeAnchor(QGraphicsView::ViewportAnchor anchor) - Qt::ItemSelectionMode rubberBandSelectionMode() const
void setRubberBandSelectionMode(Qt::ItemSelectionMode mode) - QRectF sceneRect() const
void setSceneRect(const QRectF &rect)
void setSceneRect(qreal x, qreal y, qreal w, qreal h) - QGraphicsView::ViewportAnchor transformationAnchor() const
void setTransformationAnchor(QGraphicsView::ViewportAnchor anchor) - QGraphicsView::ViewportUpdateMode viewportUpdateMode() const
void setViewportUpdateMode(QGraphicsView::ViewportUpdateMode mode)
视图位置
- void centerOn(const QPointF &pos)
void centerOn(qreal x, qreal y)
void centerOn(const QGraphicsItem *item)
滚动视口的内容以确保场景坐标pos在视图中居中。
因为pos是浮点坐标,并且滚动条在整数坐标上运行,所以居中仅是一个近似值。
注意:如果该项目靠近边界或在边界外,则它将在视图中可见,但不会居中。 - void ensureVisible(const QRectF &rect, int xmargin = 50, int ymargin = 50)
void ensureVisible(qreal x, qreal y, qreal w, qreal h, int xmargin = 50, int ymargin = 50)
void ensureVisible(const QGraphicsItem *item, int xmargin = 50, int ymargin = 50) - void fitInView(const QRectF &rect, Qt::AspectRatioMode aspectRatioMode = Qt::IgnoreAspectRatio)
void fitInView(qreal x, qreal y, qreal w, qreal h, Qt::AspectRatioMode aspectRatioMode = Qt::IgnoreAspectRatio)
void fitInView(const QGraphicsItem *item, Qt::AspectRatioMode aspectRatioMode = Qt::IgnoreAspectRatio)
仿射变换
- void scale(qreal sx, qreal sy)
- void rotate(qreal angle)
- void shear(qreal sh, qreal sv)
- void translate(qreal dx, qreal dy)
- QTransform transform() const
void setTransform(const QTransform &matrix, bool combine = false)
bool isTransformed() const
void resetTransform() - QTransform viewportTransform() const
特殊
- QGraphicsScene * scene() const
void setScene(QGraphicsScene *scene) - void setOptimizationFlag(QGraphicsView::OptimizationFlag flag, bool enabled = true)
- void setRenderHint(QPainter::RenderHint hint, bool enabled = true)
- void render(QPainter *painter, const QRectF &target = QRectF(), const QRect &source = QRect(), Qt::AspectRatioMode aspectRatioMode = Qt::KeepAspectRatio)
- void resetCachedContent()
- QRect rubberBandRect() const
项目相关
- QGraphicsItem * itemAt(const QPoint &pos) const
QGraphicsItem * itemAt(int x, int y) const - QList<QGraphicsItem *> items() const
QList<QGraphicsItem *> items(const QPoint &pos) const
QList<QGraphicsItem *> items(int x, int y) const
QList<QGraphicsItem *> items(const QRect &rect, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const
QList<QGraphicsItem *> items(int x, int y, int w, int h, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const
QList<QGraphicsItem *> items(const QPolygon &polygon, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const
QList<QGraphicsItem *> items(const QPainterPath &path, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const
坐标映射
- QPoint mapFromScene(const QPointF &point) const
QPolygon mapFromScene(const QRectF &rect) const
QPolygon mapFromScene(const QPolygonF &polygon) const
QPainterPath mapFromScene(const QPainterPath &path) const
QPoint mapFromScene(qreal x, qreal y) const
QPolygon mapFromScene(qreal x, qreal y, qreal w, qreal h) const - QPointF mapToScene(const QPoint &point) const
QPolygonF mapToScene(const QRect &rect) const
QPolygonF mapToScene(const QPolygon &polygon) const
QPainterPath mapToScene(const QPainterPath &path) const
QPointF mapToScene(int x, int y) const
QPolygonF mapToScene(int x, int y, int w, int h) const
重写的公共函数
- virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const override
- virtual QSize sizeHint() const override
公共槽
- void invalidateScene(const QRectF &rect = QRectF(), QGraphicsScene::SceneLayers layers = QGraphicsScene::AllLayers)
- void updateScene(const QList< QRectF > &rects)
- void updateSceneRect(const QRectF &rect)
信号
- void rubberBandChanged(QRect rubberBandRect, QPointF fromScenePoint, QPointF toScenePoint)
受保护的函数
- virtual void drawBackground(QPainter *painter, const QRectF &rect)
- virtual void drawForeground(QPainter *painter, const QRectF &rect)
重写的受保护的函数
- virtual void contextMenuEvent(QContextMenuEvent *event) override
- virtual void dragEnterEvent(QDragEnterEvent *event) override
- virtual void dragLeaveEvent(QDragLeaveEvent *event) override
- virtual void dragMoveEvent(QDragMoveEvent *event) override
- virtual void dropEvent(QDropEvent *event) override
- virtual bool event(QEvent *event) override
- virtual void focusInEvent(QFocusEvent *event) override
- virtual bool focusNextPrevChild(bool next) override
- virtual void focusOutEvent(QFocusEvent *event) override
- virtual void inputMethodEvent(QInputMethodEvent *event) override
- virtual void keyPressEvent(QKeyEvent *event) override
- virtual void keyReleaseEvent(QKeyEvent *event) override
- virtual void mouseDoubleClickEvent(QMouseEvent *event) override
- virtual void mouseMoveEvent(QMouseEvent *event) override
- virtual void mousePressEvent(QMouseEvent *event) override
- virtual void mouseReleaseEvent(QMouseEvent *event) override
- virtual void paintEvent(QPaintEvent *event) override
- virtual void resizeEvent(QResizeEvent *event) override
- virtual void scrollContentsBy(int dx, int dy) override
- virtual void showEvent(QShowEvent *event) override
- virtual bool viewportEvent(QEvent *event) override
- virtual void wheelEvent(QWheelEvent *event) override
受保护的槽
- virtual void setupViewport(QWidget *widget) override