Search code examples
c++qtqt4qgraphicsviewqgraphicsitem

How to add QLabel to QGraphicsItem


I have a QGraphicsItem that has text on it. I want this text to be editable, so that if the user double-clicks it, it will enter an edit mode. It seems like the easiest way to do this would be to change the text into a QLineEdit and let the user click away the focus or press enter when they're done.

How can I add a QLineEdit to a QGraphicsItem? I have subclassed the QGraphicsItem so I have access to its internals.


Solution

  • To add any QWidget based object to a QGraphicsScene, a QGraphicsProxyWidget is required.

    When you call the function addWidget on QGraphicsScene, it embeds the widget in a QGraphicsProxyWidget and returns that QGraphicsProxyWidget back to the caller.

    The QGraphicsProxyWidget forwards events to its widget and handles conversion between the different coordinate systems.

    Now that you're looking at using a QLineEdit in the QGraphicsScene, you need to decide if you want to add it directly:

    QGraphicsScene* pScene = new QGraphicsScene;
    QLineEdit* pLineEdit = new QLineEdit("Some Text");
    
    // add the widget - internally, the QGraphicsProxyWidget is created and returned
    QGraphicsProxyWidget* pProxyWidget = pScene->AddWidget(pLineEdit);
    

    Or just add it to your current QGraphicsItem. Here, you can either add it as a child of the QGraphicsItem:

    MyQGraphicsItem* pMyItem = new MyQGraphicsItem;
    QGraphicsProxyWidget* pMyProxy = new QGraphicsProxyWidget(pMyItem); // the proxy's parent is pMyItem
    pMyProxy->setWidget(pLineEdit); // adding the QWidget based object to the proxy
    

    Or you could add the QGraphicsProxyWidget as a member of your class and call its relevant functions, but adding it as a child is probably much simpler.