Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/solr/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Qt 如何从QGraphicsView发布QGLWidget_Qt_Destructor_Qgraphicsview_Qglwidget - Fatal编程技术网

Qt 如何从QGraphicsView发布QGLWidget

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”会导致崩

我看到许多关于使用OpenGL进行图形视图的Qt示例。 大多数样本如下所示:

MyGraphicsView::MyGraphicsView(......)
{
gl = new QGLWidget();
this->setViewport(gl);
....
其中QGLWidget*gl是MyGraphicsView的成员

我的问题是,在这之后我应该如何删除“gl”。 它会随着从QGraphicsView继承的类自动删除吗? 手动删除MyGraphicsView描述器中的“gl”会导致崩溃

在Qt中,很难理解哪些对象将被自动删除,哪些不被自动删除

在Qt中,很难理解哪些对象将被自动删除,哪些不被自动删除

一点也不。你只需要知道两件事:

  • C++作用域的语义。但你已经知道这些了——希望如此

  • 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
    实例

  • 手动删除MyGraphicsView描述器中的“gl”会导致崩溃

    不,没有,除非你没有告诉我们什么。以下内容在Qt 4和Qt 5中都可以正常工作。手动删除是无害的,尽管完全没有必要:

    // 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();
    }