Question

I coded a small QT program using QGLWidget. The goal is to display a simple triangle in permanent rotation. The problem is that there is no animation because just the first frame is rendered.

Here's my main C++ source code :

#include "qtapplication.h"
#include <QtWidgets/QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QtApplication w;
    w.show();
    return a.exec();
}

My qtapplication.h file :

include <QtWidgets/QMainWindow>
#include "ui_qtapplication.h"
#include "HSGLWidget.hpp"

class QtApplication : public QMainWindow
{
    Q_OBJECT

public:
    QtApplication(QWidget *parent = 0);
    ~QtApplication();

private:
    Ui::QtApplicationClass ui;
    HSGLWidget *_glwidget;
};

My qtapplication.cpp file :

#include "qtapplication.h"

QtApplication::QtApplication(QWidget *parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);
    this->_glwidget = NULL;

    if (this->_glwidget == NULL)
        this->_glwidget = new HSGLWidget();
    this->_glwidget->setVisible(true);
    setCentralWidget(this->_glwidget);
}

QtApplication::~QtApplication()
{

}

My HSGLWidjet.h file:

#include <QGLWidget>

class HSGLWidget : public QGLWidget {

    Q_OBJECT
    public:
        explicit HSGLWidget(QWidget *parent = 0);
        virtual ~HSGLWidget();

    protected:
        virtual void initializeGL();
        virtual void resizeGL(int width, int height);
        virtual void paintGL();

        virtual void keyPressEvent(QKeyEvent *keyEvent);

    private:
        void _onSetup();

    private:
        QTimer  *_timer;
};

And my HSGLWidjet.cpp file:

#include <iostream>
#include "HSGLWidget.hpp"

float toto_angle = 0.0f;

HSGLWidget::HSGLWidget(QWidget *parent) 
    :  QGLWidget(parent)
{
    this->_onSetup();
}

HSGLWidget::~HSGLWidget(void)
{

}

void HSGLWidget::initializeGL()
{   
    glShadeModel(GL_SMOOTH);
    glClearColor(0.0f, 0.20f, 0.0f, 0.0f);
    glClearDepth(1.0f);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
}

void HSGLWidget::resizeGL(int width, int height)
{
    if (height == 0)
        height = 1;
    glViewport(0, 0, width, height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45.0f, (GLfloat)width / (GLfloat)height, 0.1f, 100.0f);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

void HSGLWidget::paintGL(void)
{
    std::cout << "PAINTGL" << std::endl;

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
    glTranslatef(-1.5f, 0.0f, -6.0f);

    glEnable(GL_MODELVIEW);

    glPushMatrix();

    glTranslatef(0.0f, 0.0f, 0.0f);
    glRotatef(toto_angle, 1.0f, 1.0f, 1.0f);
    glScalef(1.0f, 1.0f, 1.0f);

    glBegin(GL_TRIANGLES);
    glColor3ub(255, 0, 0);
    glVertex3f(0.0f, 0.75f, 0.0f);
    glColor3ub(0, 255, 0);
    glVertex3f(-0.75f, 0.0f, 0.0f);
    glColor3ub(0, 0, 255);
    glVertex3f(0.75f, 0.0f, 0.0f);
    glEnd();

    toto_angle+=1.0f;
    glPopMatrix();
}

void HSGLWidget::keyPressEvent(QKeyEvent *keyEvent)
{

}

void HSGLWidget::_onSetup()
{

}

The string 'PAINTGL' is written just for the first frame. Normally, paintGL is called automatically. I'm really lost in front of this situation. Does anyone can help me, please ? Thanks a lot in advance for your help.

Was it helpful?

Solution

There's no problem at all, that's the standard behavior.

You see, paint() and paintGL() are called only when the window needs to be draw. That is: when your application is created, when the window is resized, or moved around. Only then paintGL() is triggered. That's it!

If you want it to be called more than once, you will need to add a timer to execute update(), which is a method that forces the window to be redraw, which in turn triggers paintGL(). Do not call paintGL() directly!

QTimer can help you achieve what you are looking for!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top