c++qtqwidgetqgraphicssceneqgraphicswidget

Why is the selection border of a QGraphicsWidget not visible in QGraphicsScene?


I have added a widget to a graphic scene (QGraphicScene) through a QGraphicsProxyWidget. The problem is that when I select the item it's selected, but the selection border is not visible.

Here is the code:

    QDial *dial= new QDial(); // Widget 
    dial->setGeometry(3,3,100,100);// setting offset for graphicswidget and widget

    QGraphicsWidget *ParentWidget = new QGraphicsWidget();// created to move and select on scene
    ParentWidget->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
    Scene->addItem(ParentWidget); // adding to scene

    QGraphicsProxyWidget *proxy = new QGraphicsProxyWidget();// adding normal widget through this one
    proxy->setWidget( DialBox );
    proxy->setParentItem(ParentWidget);

Here is the output:

Output

How could I fix this?


Solution

  • Cause

    QGraphicsWidget does not paint anything (including a selection rectangle), as seen from the source code:

    void QGraphicsWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
    {
        Q_UNUSED(painter);
        Q_UNUSED(option);
        Q_UNUSED(widget);
    }
    

    QGraphicsRectItem, however, does (see the source code):

    void QGraphicsRectItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
                                  QWidget *widget)
    {
        ...
    
        if (option->state & QStyle::State_Selected)
            qt_graphicsItem_highlightSelected(this, painter, option);
    }
    

    Solution

    My solution would be to use QGraphicsRectItem instead of QGraphicsWidget as a handle to select/move the dial like this:

    auto *dial= new QDial();                                        // The widget
    auto *handle = new QGraphicsRectItem(QRect(0, 0, 120, 120));    // Created to move and select on scene
    auto *proxy = new QGraphicsProxyWidget(handle);                 // Adding the widget through the proxy
    
    dial->setGeometry(0, 0, 100, 100);
    dial->move(10, 10);
    
    proxy->setWidget(dial);
    
    handle->setPen(QPen(Qt::transparent));
    handle->setBrush(Qt::gray);
    handle->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
    
    Scene->addItem(handle); // adding to scene
    

    This code produces the following result:

    enter image description here

    Click the dark gray area around the dial widget to select/move it or the widget itself in order to interact with it.