之前我从QGLWidget派生出来,就像这样:
class MyGLWidget : public QGLWidget
{
public:
// stuff...
virtual void initializeGL() { /* my custom OpenGL initialization routine */ }
// more stuff...
};
但是,我发现如果我尝试使用我的自定义QGLWidget作为视口初始化QGraphicsView,则不会调用initializeGL(在Qt库中设置断点,在创建简单时QGLWidget :: initializeGL()也不会)
// initializeGL, resizeGL, paintGL not called
ui.graphicsView->setViewport(new MyGLWidget(QGLFormat(QGL::DoubleBuffer)));
// initializeGL, resizeGL, paintGL *still* not called
ui.graphicsView->setViewport(new QGLWidget(QGLFormat(QGL::DoubleBuffer)));
放置当前位于MyGLWidget :: initializeGL()中的代码的正确位置在哪里?
答案 0 :(得分:4)
自定义QGraphicsView的setupViewport插槽可用于调用QGLWidget上的updateGL(),这将导致调用initializeGL()。
class MyGraphicsView : public QGraphicsView
{
//... The usual stuff
protected slots:
virtual void setupViewport(QWidget *viewport)
{
QGLWidget *glWidget = qobject_cast<QGLWidget*>(viewport);
if (glWidget)
glWidget->updateGL();
}
};
答案 1 :(得分:2)
所以我发现QGraphicsView在你的QGLWidget视口上安装了一个自定义的eventFilter,所以它永远不会看到初始化/调整大小/重绘事件。这可能是为了使它与drawBackground()等一起正常工作。
我目前的最佳解决方案是在QGraphicsView :: resizeEvent()/ etc中捕获所需的事件,或者在QGLWidget派生类上安装自定义eventFilter以在QGraphicsView的自定义eventFilter吞下它们之前捕获resize / paint / etc事件。
答案 2 :(得分:1)
痛苦,痛苦,......将QGlWidgets派生的小部件整合到QGraphicsView中并不好玩,Qt的各个部分我知道这绝对是一个混乱的领域。我最终使用名为widgetproxy的kgllib(在kde之外)的一部分,这是一个围绕QGlWidget的非常好的包装器。我修改它以满足我的需要,但是对于大多数一般情况你要使用QGlWicsView中的QGlWidget派生的现有类并在其上绘制其他东西时效果相当好。
答案 3 :(得分:0)
initializeGL()
或paintGL()
之前, resizeGL()
将不会被调用,而不是在构建小部件时调用。这可能发生在窗口小部件首次可见时。
答案 4 :(得分:0)
我要继续回答我自己的问题。这不是最佳选择,但这就是我解决问题的方法。
而不是
ui.graphicsView->setViewport(new MyGLWidget(QGLFormat(QGL::DoubleBuffer)));
我得到了这个:
ui.graphicsView->setViewport(new QGLWidget(new CustomContext(QGLFormat(QGL::SampleBuffers))));
CustomContext是一个派生自QGLContext的类。我已经覆盖了创建成员,如下所示:
virtual bool create(const QGLContext *shareContext = 0)
{
if(QGLContext::create(shareContext))
{
makeCurrent();
/* do my initialization here */
doneCurrent();
return true;
}
return false;
}
我认为这不是最佳方法,但它比没有特定初始化步骤的替代方案更好。我仍然很乐意让别人留下更好的答案!