3

The following code is based on the documentation of Graphics View Framework. I embed a QLineEdit in a QGraphicsScene and run the program. When I right click the line edit in the scene I get a clipped context menu. The context menu of a QGraphicsProxyWidget is drawn by the scene as a child QGraphicsProxyWidget so it get's clipped if the window is too small. I want all embedded widgets to show their context menus as top-level windows like they do when not being embedded in a QGraphicsScene. I have tried the BypassGraphicsProxyWidget flag in two ways but it doesn't work as I want. Tested on Qt 4.8 / 5.0 on Linux and Windows. Same issue on all platforms.

How can I make the embedded widgets display normal, top-level context menus with native look? Overloading QGraphicsView's contextMenuEvent gives a native top-level context menu - could I do some sort of delegation and make QGraphicsView display the context menu of embedded widgets in the scene?

#include <QApplication>
#include <QLineEdit>
#include <QGraphicsScene>
#include <QGraphicsProxyWidget>
#include <QGraphicsView>

int main(int argc, char **argv)
{
    QApplication app(argc, argv);

    QGraphicsScene scene;
    QGraphicsProxyWidget *proxy = scene.addWidget(new QLineEdit(), Qt::BypassGraphicsProxyWidget);

    QGraphicsView view(&scene);
    view.setWindowFlags(Qt::BypassGraphicsProxyWidget);
    view.show();

    return app.exec();
}
user1284878
  • 75
  • 1
  • 9

2 Answers2

1

Unfortunately, this is a known bug QTBUG-10683. A workaround is suggested in the last comment to the bug report.

Oleg Shparber
  • 2,732
  • 1
  • 18
  • 19
  • 1
    I found you have to add a QWidget that has the bypass flag set then for it's children, context menus will be native ones. Solved. – user1284878 Dec 29 '12 at 19:24
1

You get native context menus by adding a QWidget that has the Qt::BypassGraphicsProxyWidget set. Children will render it's context menus as pop-ups native style.

#ifndef QGLPARENT_H
#define QGLPARENT_H

#include <QGLWidget>
#include <QGraphicsScene>
#include <QGraphicsProxyWidget>
#include <QGraphicsView>

class QGLParent : public QGraphicsView
{
private:
    QGraphicsProxyWidget *child;
public:
    QGLParent(QWidget *parent, QWidget *child) : QGraphicsView(parent)
    {
        setFrameShape(QFrame::NoFrame);
        QGLFormat format(QGL::SampleBuffers);
        format.setSwapInterval(1);

        setScene(new QGraphicsScene());
                setViewport(new QGLWidget(format));
                //setViewportUpdateMode(QGraphicsView::FullViewportUpdate);

        child->setWindowFlags(Qt::BypassGraphicsProxyWidget);
        this->child = scene()->addWidget(child);
    }
protected:
    void resizeEvent(QResizeEvent *event)
    {
        scene()->setSceneRect(QRect(QPoint(0, 0), event->size()));
        child->resize(event->size().width(), event->size().height());
        QGraphicsView::resizeEvent(event);
    }
};

#endif
user1284878
  • 75
  • 1
  • 9