Search code examples
c++qtqt3d

Class object in mainwindow.h in Qt


I am trting to open a new window (window with the cubeview view in qt3d application) whenever a button is clicked on the main window.

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "cubeview.h"

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    int getid();

public slots:
    void pattern1();

private:
    CubeView *view;
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

and mainwindow .cpp file

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPushButton>
#include <iostream>
#include "cubeview.h"

int pattern_id;
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    QPushButton *button= new QPushButton("Pattern 1");
    QObject::connect(button, SIGNAL(clicked()), this,  SLOT(pattern1()));
    button->show();
    std::cout<<"reached mainwindow constructor"<<std::endl;
    //view= new CubeView;

}
void MainWindow::pattern1()
{
    pattern_id=1;
    view->begin(1);
    view->resize(800, 600);
    view->show();
    std::cout<<pattern_id<<std::endl;
}
int MainWindow::getid()
{
    return pattern_id;
}
MainWindow::~MainWindow()
{
    delete ui;
    delete view;
}

I get a runtime error.

I hope you get what i am trying to do. Whenever i click on the push button, the cubeview view window should show up. What is the mistake i am making? Where should I define the cubeView class object so that I can use it later. Can I initialize it as CubeView *view= new CubeView; in a header file. I tried to write it in the constructor of mainwindow.cpp but i get a runtime error.

#ifndef CUBEVIEW_H
#define CUBEVIEW_H

#include "qglview.h"
#include "qgltexture2d.h"

QT_BEGIN_NAMESPACE
class QGLSceneNode;
QT_END_NAMESPACE

//! [1]
class CubeView : public QGLView
{
//! [1]
    Q_OBJECT

public:
    CubeView(QWidget *parent = 0);
    ~CubeView();
    void begin(int pattern_id);

public slots:
    void update_action();

protected:
    void paintGL(QGLPainter *painter);

    //! [2]
private:
    QGLSceneNode *cube;
    QGLSceneNode *cursor;
    QGLTexture2D logo;
    QGLTexture2D* texture;
    QGLTexture2D handcursor;

};
//! [2]

#endif


//! [1] constructor, initialize the cube, cursor and camera
CubeView::CubeView(QWidget *parent)
{
    //! [1] draw the paintboard
    QVector3D *cube1_pos= new QVector3D(0.0,0.0,-1.5);
    QGLBuilder builder1;
    builder1 << QGL::Faceted;
    builder1 << QGLCube(3.25);
    cube = builder1.finalizedSceneNode();
    cube->setPosition(*cube1_pos);

    //draw the cursor
    QGLBuilder cursor_builder;
    cursor_builder <<QGL::Faceted;
    cursor_builder <<QGLCube(0.15);
    cursor=cursor_builder.finalizedSceneNode();

    //camera setup
    camera()->setFieldOfView(35);
    camera()->setNearPlane(1);
    camera()->setFarPlane(15);

    //! [2] set texture for cube and cursor
    //QImage image(QLatin1String(":/bluecircle.jpg"));

    handcursor.setImage(QImage(QLatin1String(":/hand.jpg")));
    std::cout<<"constructor called"<<std::endl;


}

Solution

  • I think I finally found my answer. It has nothing to to do with the definition of the cubeview class constructor. The simple principle is that -> we need not create a class object within a loop or the program code crashes. -> also the view.show if directly put inside a connect slot , will run into the error of an infinite loop. Here is the answer.

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include <QPushButton>
    #include <iostream>
    #include "cubeview.h"
    
    
    int pattern_id;
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        view=0;
    
        std::cout<<"reached mainwindow constructor"<<std::endl;
         QPushButton *button= new QPushButton("Pattern 1");
           QObject::connect(button, SIGNAL(clicked()), this,  SLOT(pattern1()));
           button->show();
    
       else if(view!=NULL)
        {
            std::cout<<"view is already initialized"<<std::endl;
        }
    
    
    }
    void MainWindow::pattern1()
    {
    
      if(view==NULL)
        {
            view=new CubeView;
            view->begin(1);
            view->resize(800, 600);
                view->show();
    
        }
    }
    int MainWindow::getid()
    {
        return pattern_id;
    }
    MainWindow::~MainWindow()
    {
        delete ui;
            delete view;
    }

    In this way, the new object window is created if the value is already NULL.