1

I would like to embed a QWidget such as a push button or progress bar in my QGraphicswidget, but I have only seen examples of adding a QWidget to a QGraphicsScene i.e.

m_scene->addWidget(new QPushButton("Test Test"));

In my custom graphics widget I am drawing text and other custom shapes in the paint function. I would think you would need to add the QWidget here, but I'm probably wrong. Does anyone know how to do this?

Here is my overloaded paint function:

void TestWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem 
    *option, QWidget *widget /*= 0*/)
{
    Q_UNUSED(widget);
    Q_UNUSED(option);

    QRectF frame(QPointF(0,0), geometry().size());
    QGradientStops stops;   

    //Draw border
    painter->drawRoundedRect(boundingRect(), 5.0, 5.0);
    //Name of the test
    painter->drawText(40, 20, m_name);

    //Status of test
    QFont font = painter->font() ;
    font.setPointSize(14);
    painter->setFont(font);
    painter->drawText(600, 20, m_status);

    //Arrow button
    QPolygonF poly;
    poly << QPointF(5, 10) << QPointF(25, 10) << QPointF(15, 20 )<< 
    QPointF(5,10);
    painter->setBrush(Qt::black);
    painter->drawPolygon(poly, Qt::OddEvenFill);   
}
scopchanov
  • 7,966
  • 10
  • 40
  • 68
Michael Japzon
  • 201
  • 1
  • 2
  • 10
  • use `QGraphicsProxyWidget`. – eyllanesc Aug 23 '18 at 19:36
  • The examples you are referencing show how to add a QWidget to a QGraphicsScene. They do not show how to embed a QWidget inside a QGraphicsWidget. – Michael Japzon Aug 23 '18 at 19:47
  • 2
    you have to use: `QGraphicsProxyWidget`, `QGraphicsProxyWidget *proxy = new QGraphicsProxyWidget` `proxy->setWidget(pointer_of_your_widget);` `m_scene->addItem(proxy)`. see http://doc.qt.io/qt-5/qtwidgets-graphicsview-basicgraphicslayouts-example.html – eyllanesc Aug 23 '18 at 19:51
  • @scopchanov I have added a custom QGraphicsWidget to a scene, and within that QGraphicsWidget I would like to add a QProgressBar. – Michael Japzon Aug 23 '18 at 20:14
  • @scopchanov I need to draw a large number of 2d items thus regular QWidgets will not work. It will hopefully only be a rare case (one or two times) that I will need to draw a QWidget within my QGraphicsWidget. Since I'm using QGraphicWidgets I need a QGraphicScene to draw them correct? – Michael Japzon Aug 23 '18 at 20:33

1 Answers1

2

Solution

In order to embed a widget, e.g. QPushButton, in your subclass of QGraphicsWidget use QGraphicsProxyWidget like this:

#include "TestWidget.h"
#include <QGraphicsProxyWidget>
#include <QPushButton>

TestWidget::TestWidget(QGraphicsItem *parent) :
    QGraphicsWidget(parent)
{
    ...
    auto *proxy = new QGraphicsProxyWidget(this);
    
    proxy->setWidget(new QPushButton(tr("CLick me")));
    proxy->moveBy(20, 40);
    ...
}

Background

If you use m_scene->addWidget(new QPushButton("Test Test"));, which is essentially the same as:

QGraphicsProxyWidget *proxy = new QGraphicsProxyWidget();

proxy->setWidget(new QPushButton("Test Test"));
m_scene->addItem(proxy);

you add the QPushButton (through the proxy) directly to the scene.

If you want to make the QPushButton a part of your custom QGraphicsWidget, set the parent of the QGraphicsProxyWidget to the instance of the custom QGraphicsWidget.

Note: There is no need to call QGraphicsScene::addItem, as (because of the parent/child relationship) the proxy will be added to the scene together with your custom QGraphicsWidget.


Result

Using your paint method the result is similar to this:

enter image description here

Community
  • 1
  • 1
scopchanov
  • 7,966
  • 10
  • 40
  • 68