본문 바로가기
Solution/Qt Programming

[Qt] Rotating Teapot in MDI Window

by 이센 2023. 8. 26.

이번 예제는 Qt MDI Win이번 예제는 openGL glut 라이브러리를 이용하여 3D 도형을 그리고, 도형을 저장하는 코드이다. 도형을 선택하고 저장 및 인쇄하는 명령은 메인 윈도우의 컨트롤 상자에서 제어한다.

 

다음 목표는 '.grd', '.dat' 파일을 읽고 이 결과를 Shader 없이 OpenGL 로 구현하는 것인데, 이럴려면, 잘 알려진 3D Model File 형식으로 변환하는 것이 필요하다. 현재는 '.obj' 파일이 적당해 보여, 이 걸 구현하려한다.  

#1 project file 


QT       += core gui opengl

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = MDI04
TEMPLATE = app

# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

CONFIG += c++11

SOURCES += \
        main.cpp \
        mainwindow.cpp \
    mdimainwindow.cpp \
    glwidget.cpp

HEADERS += \
        mainwindow.h \
    mdimainwindow.h \
    glwidget.h

INCLUDEPATH += "D:/Work/2023/01_Qt/MDI04/openGL"

LIBS += -L"D:/Work/2023/01_Qt/MDI04/lib"

LIBS += -lopengl32 -lglut64


# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

여전히 컴파일 시에 어떤 project 는 동일하게 만들어도 crash 가 나는 경우가 있다. 하지만, 아직 원인을 찾지 못하고 있다.

 

#2 <glwidget.h> 

#ifndef GLWIDGET_H
#define GLWIDGET_H

#include <QGLWidget>

class GLWidget : public QGLWidget
{
    Q_OBJECT

public:
    explicit GLWidget(QWidget *parent = 0);


public slots:
    void initializeGL();
    void paintGL();
    void resizeGL(int w, int h);

    void setXRotation(int angle);
    void setYRotation(int angle);
    void setZRotation(int angle);
    void resetRotation();

private:
    int xRot;
    int yRot;
    int zRot;

};

#endif // GLWIDGET_H

#3 <glwidget.cpp> 

#include "glwidget.h"
#include "glut.h"

GLWidget::GLWidget(QWidget *parent) :
    QGLWidget(parent)
{
    xRot = 0;
    yRot = 0;
    zRot = 0;
}

void GLWidget::setXRotation(int angle)
{
    xRot = angle;
    updateGL();

}

void GLWidget::setYRotation(int angle)
{
    yRot = angle;
    updateGL();
}

void GLWidget::setZRotation(int angle)
{
    zRot = angle;
    updateGL();

}

void GLWidget::resetRotation()
{
    xRot= yRot = zRot= 0;
    updateGL();
}

void GLWidget::initializeGL() {


}

void GLWidget::paintGL() {

   glClear(GL_COLOR_BUFFER_BIT);
   glLoadIdentity();

   glRotatef(xRot, 1.0, 0.0, 0.0);
   glRotatef(yRot, 0.0, 1.0, 0.0);
   glRotatef(zRot, 0.0, 0.0, 1.0);

   glutWireTeapot(0.6);

}


void GLWidget::resizeGL(int w, int h)
{

    glViewport(0,0,w,h);

}

#4 <mainwindow.h> 

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

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

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:

private slots:
    void newFile();
    void open();
};

#endif // MAINWINDOW_H

#5 <mainwindow.cpp> 

#include "mainwindow.h"
#include <QMenu>
#include <QAction>
#include <QMenuBar>
#include <QToolBar>
#include <QDockWidget>
#include <QListWidget>
#include <QStatusBar>
#include <QDebug>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    QMenu *fileMenu;
    QAction *newAct;
    QAction *openAct;

    newAct = new QAction(QIcon(":/images/new.png"), tr("&New"), this);
    newAct->setShortcuts(QKeySequence::New);
    newAct->setStatusTip(tr("Create a new file"));
    connect(newAct, SIGNAL(triggered()), this, SLOT(newFile()));

    openAct = new QAction(QIcon(":/images/open.png"), tr("&Open"), this);
    openAct->setShortcuts(QKeySequence::Open);
    openAct->setStatusTip(tr("Open an existing file"));
    connect(openAct, SIGNAL(triggered()), this, SLOT(open()));

    fileMenu = menuBar()->addMenu(tr("&File"));
    fileMenu->addAction(newAct);
    fileMenu->addAction(openAct);

    QToolBar *fileToolBar;
    fileToolBar = addToolBar(tr("File"));
    fileToolBar->addAction(newAct);
    fileToolBar->addAction(openAct);

    QDockWidget *dock = new QDockWidget(tr("Target"), this);
    dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);

    QListWidget *customerList = new QListWidget(dock);
    customerList->addItems(QStringList()
            << "One"
            << "Two"
            << "Three"
            << "Four"
            << "Five");

    dock->setWidget(customerList);
    addDockWidget(Qt::RightDockWidgetArea, dock);

    setCentralWidget(new MDIMainWindow());


    statusBar()->showMessage(tr("Ready"));

}

MainWindow::~MainWindow()
{

}

// [SLOTS]
void MainWindow::newFile()
{
    qDebug() << Q_FUNC_INFO;
}

void MainWindow::open()
{
    qDebug() << Q_FUNC_INFO;
}

 

#6 <mdimainwindow.h> 

#ifndef QMDIMAINWINDOW_H
#define QMDIMAINWINDOW_H

#include <QMainWindow>
#include <QObject>

class MDIMainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MDIMainWindow(QWidget *parent = nullptr);
};

#endif // QMDIMAINWINDOW_H

 

 

#7 <mdimainwindow.cpp>

#include "mdimainwindow.h"
#include <QMdiArea>
#include <QMdiSubWindow>
#include <QPushButton>
#include <QSlider>
#include "glwidget.h"

MDIMainWindow::MDIMainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    setWindowTitle(QString::fromUtf8("My MDI"));

    QMdiArea* area = new QMdiArea();
    area->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);

    // MdiSubWindow 생성
    QMdiSubWindow* subWindow1 = new QMdiSubWindow();
    subWindow1->setGeometry(10,10, 300, 400);

    QPushButton *btn1 = new QPushButton(subWindow1);
    QPushButton *btn2 = new QPushButton(subWindow1);

    QSlider *xRotationSlider = new QSlider(subWindow1);
    QSlider *yRotationSlider = new QSlider(subWindow1);
    QSlider *zRotationSlider = new QSlider(subWindow1);


    btn1->setText("Close1");
    btn1->setGeometry(20,80,90,30);

    btn2->setText("Close2");
    btn2->setGeometry(20,130,90,30);

    xRotationSlider->setGeometry(20,180,30,90);
    yRotationSlider->setGeometry(50,180,30,90);
    zRotationSlider->setGeometry(80,180,30,90);



    QMdiSubWindow* subWindow2 = new QMdiSubWindow();

    GLWidget* screen = new GLWidget(subWindow2);
    screen->setGeometry(40,100, 600, 400);
    screen->setStyleSheet("QLineEdit {background-color:black}");
    screen->show();

    subWindow2->setGeometry(310, 10, 700, 600);


    QObject::connect(btn1, &QPushButton::clicked,subWindow1, &QMdiSubWindow::close);
    QObject::connect(btn2, &QPushButton::clicked,subWindow2, &QMdiSubWindow::close);
    //QOjbect::connect(slider1, &QSlider::update, )

    // MDIMainWindows에 서브 윈도우 추가
    area->addSubWindow(subWindow1);
    area->addSubWindow(subWindow2);


    //connect(resetButton, SIGNAL(clicked()),screen, SLOT(resetRotation()));


    setCentralWidget(area);

    connect(xRotationSlider, SIGNAL(valueChanged(int)), screen, SLOT(setXRotation(int)));
    connect(yRotationSlider, SIGNAL(valueChanged(int)), screen, SLOT(setYRotation(int)));
    connect(zRotationSlider, SIGNAL(valueChanged(int)), screen, SLOT(setZRotation(int)));
}

 

 

#8 <main.cpp>  

#include "mainwindow.h"
#include <QApplication>
#include "glut.h"

int main(int argc, char *argv[])
{
    glutInit(&argc, argv);
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

MDI04.zip
9.23MB