Qt 如何从QGraphicsView发布QGLWidget
我看到许多关于使用OpenGL进行图形视图的Qt示例。 大多数样本如下所示:Qt 如何从QGraphicsView发布QGLWidget,qt,destructor,qgraphicsview,qglwidget,Qt,Destructor,Qgraphicsview,Qglwidget,我看到许多关于使用OpenGL进行图形视图的Qt示例。 大多数样本如下所示: MyGraphicsView::MyGraphicsView(......) { gl = new QGLWidget(); this->setViewport(gl); .... 其中QGLWidget*gl是MyGraphicsView的成员 我的问题是,在这之后我应该如何删除“gl”。 它会随着从QGraphicsView继承的类自动删除吗? 手动删除MyGraphicsView描述器中的“gl”会导致崩
MyGraphicsView::MyGraphicsView(......)
{
gl = new QGLWidget();
this->setViewport(gl);
....
其中QGLWidget*gl是MyGraphicsView的成员
我的问题是,在这之后我应该如何删除“gl”。
它会随着从QGraphicsView继承的类自动删除吗?
手动删除MyGraphicsView描述器中的“gl”会导致崩溃
在Qt中,很难理解哪些对象将被自动删除,哪些不被自动删除
在Qt中,很难理解哪些对象将被自动删除,哪些不被自动删除
一点也不。你只需要知道两件事:
QObject::~QObject()
删除其幸存的子对象:
QObject::~QObject() {
...
for (auto child : children())
delete child;
...
}
显然,如果子对象在进入~QObject()
之前已被销毁,则它不会出现在父对象的子对象()
列表中,也不会被双重删除。这似乎在某种程度上把大多数人都甩了,但如果你不把Qt看作是某种魔力的话,它就不应该被甩了。Qt做C++允许的事情。不多不少class MyGraphicsView : public QGraphicsView {
QOpenGLWidget m_gl;
public:
MyGraphicsView(QWidget * parent = nullptr) : QGraphicsView{parent} {
setViewport(&m_gl); // sets m_gl's parent
Q_ASSERT(m_gl.parent());
}
};
~MyGraphicsView
主体返回后,m\u gl
成员将被销毁。以下是销毁顺序:
this->~MyGraphicsView()
m_gl.~QOpenGlWidget() // the viewport widget ceases to exist here
this->~QGraphicsView()
this->~QAbstractScrollArea()
this->~QFrame()
this->~QWidget()
this->~QObject() // has no children to delete
this->~MyGraphicsView()
m_gl.~pointer // a trivial destructor of a pointer value
this->~QGraphicsView()
this->~QAbstractScrollArea()
this->~QFrame()
this->~QWidget()
this->~QObject()
for (auto child : children())
delete child
~QOpenGlWidget() // m_gl is long gone at this point!
~QObject()
析构函数执行时具有父对象。回想一下,所有小部件都是QObject
s
在上面的示例中,m_gl
对象将在运行MyGraphicsView::~QObject
之前被销毁,因此不存在双重销毁的可能性
但你也可能有过早悲观的指针方法:
// Don't code like this. It's silly.
class MyGraphicsView : public QGraphicsView {
QOpenGLWidget * m_gl;
public:
MyGraphicsView(QWidget * parent = nullptr) :
QGraphicsView{parent},
m_gl{new QOpenGLWidget}
{
setViewport(m_gl); // sets m_gl's parent
Q_ASSERT(m_gl->parent());
}
~MyGraphicsView() {
Q_ASSERT(m_gl->parent()); // make sure ~QObject will delete the child
}
};
以下是销毁顺序:
this->~MyGraphicsView()
m_gl.~QOpenGlWidget() // the viewport widget ceases to exist here
this->~QGraphicsView()
this->~QAbstractScrollArea()
this->~QFrame()
this->~QWidget()
this->~QObject() // has no children to delete
this->~MyGraphicsView()
m_gl.~pointer // a trivial destructor of a pointer value
this->~QGraphicsView()
this->~QAbstractScrollArea()
this->~QFrame()
this->~QWidget()
this->~QObject()
for (auto child : children())
delete child
~QOpenGlWidget() // m_gl is long gone at this point!
由于m_gl
成员的销毁非常简单,并且不会对指针本身指向的内容做任何处理,QOpenGlWidget
实例会一直存在,直到QObject
析构函数运行,在这一点上,它迭代它的子列表并delete
s每个子列表-从而删除QOpenGlWidget
实例// https://github.com/KubaO/stackoverflown/tree/master/questions/opengl-viewport-val-39750134
#include <QtGui>
#include <QtOpenGL>
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
#include <QtWidgets>
#else
using QOpenGLWidget = QGLWidget;
#endif
// Don't code like this. It's silly.
class MyGraphicsView : public QGraphicsView {
QOpenGLWidget * m_gl = new QOpenGLWidget;
public:
MyGraphicsView(QWidget * parent = nullptr) : QGraphicsView{parent}
{
setViewport(m_gl); // sets m_gl's parent
Q_ASSERT(m_gl->parent());
}
~MyGraphicsView() {
delete m_gl; // completely unnecessary
}
};
int main(int argc, char ** argv) {
QApplication app{argc, argv};
MyGraphicsView view;
QGraphicsScene scene;
scene.addText("Hello World");
view.setScene(&scene);
view.show();
return app.exec();
}
//https://github.com/KubaO/stackoverflown/tree/master/questions/opengl-viewport-val-39750134
#包括
#包括
#如果QT\u版本>=QT\u版本检查(5,0,0)
#包括
#否则
使用QOpenGLWidget=QGLWidget;
#恩迪夫
//不要这样编码。这很愚蠢。
类MyGraphicsView:公共QGraphicsView{
QOpenGLWidget*m_gl=新QOpenGLWidget;
公众:
MyGraphicsView(QWidget*parent=nullptr):QGraphicsView{parent}
{
setViewport(MU gl);//设置MU gl的父对象
Q_断言(m_gl->parent());
}
~MyGraphicsView(){
删除m_gl;//完全不需要
}
};
int main(int argc,字符**argv){
QApplication app{argc,argv};
MyGraphicsView视图;
QsCENE场景;
scene.addText(“你好世界”);
视图。设置场景(和场景);
view.show();
返回app.exec();
}